一种播放远程 TS 格式媒体文件的新方案
作者:Changing Lin
- 2021 年 12 月 23 日
本文字数:2062 字
阅读完需:约 7 分钟
1.背景
有一个需求是,有一个录音回放页面,支持播放服务器上的录像文件,容器格式为 TS,音频编码为 opus,视频为 h264。尝试使用 Google ExoPlayer 来播放,但发现有画面无声音,原因是不支持音频对应的 pid,无正确解析。今天尝试使用 vlc 库来处理,实践证明,vlc 的兼容性会更强一些,可以正常实现播放的需求,音频、视频解码正常。
2.集成与编译问题修复
修改 build.gradle 添加 libvlc 依赖:
implementation 'org.videolan.android:libvlc-all:3.4.7'复制代码
可能出现的编译失败报错
More than one file was found with OS independent path 'lib/arm64-v8a/libc++_shared.so'复制代码
解决方法:
packagingOptions { exclude 'META-INF/androidx.legacy_legacy-support-v4.version' exclude 'META-INF/annotation-experimental_release.kotlin_module' pickFirst 'lib/arm64-v8a/libc++_shared.so' // 添加这两行 pickFirst 'lib/armeabi-v7a/libc++_shared.so' }复制代码
2.原理
activity_player.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:keepScreenOn="true" android:background="@android:color/background_dark">
<org.videolan.libvlc.util.VLCVideoLayout android:id="@+id/video_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="false"/>
</FrameLayout>
复制代码
PlayerActivity.java
/***************************************************************************** * JavaActivity.java ***************************************************************************** * Copyright (C) 2016-2019 VideoLAN * All rights reserved. * * This software may be modified and distributed under the terms * of the BSD license. See the LICENSE file for details. *****************************************************************************/import android.net.Uri;import android.os.Bundle;import android.text.TextUtils;
import androidx.appcompat.app.AppCompatActivity;
import com.besmart.annotation.BindPath;import com.nufront.trunking.common.basic.BaseActivity;import com.nufront.trunking.common.system.LogUtil;import com.nufront.trunking.common.system.ToastUtil;
import org.videolan.libvlc.LibVLC;import org.videolan.libvlc.Media;import org.videolan.libvlc.MediaPlayer;import org.videolan.libvlc.util.VLCVideoLayout;
import java.util.ArrayList;
public class PlayerActivity extends BaseActivity { private static final boolean USE_TEXTURE_VIEW = false; private static final boolean ENABLE_SUBTITLES = true; private static final String ASSET_FILENAME = "bbb.m4v";
private VLCVideoLayout mVideoLayout = null;
private LibVLC mLibVLC = null; private MediaPlayer mMediaPlayer = null; private String mRemoteUrl;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
if (null == getIntent() || !getIntent().hasExtra("url")){ ToastUtil.showToast(getApplication(), R.string.config_bundle_miss_data_tip); finish(); return; } // 格式为:http://ip:port/xxx.ts mRemoteUrl = getIntent().getStringExtra("url"); LogUtil.printE(PlayerActivity.class, "播放地址: "+mRemoteUrl);
setContentView(R.layout.activity_vlc);
final ArrayList<String> args = new ArrayList<>(); args.add("-vvv"); mLibVLC = new LibVLC(this, args); mMediaPlayer = new MediaPlayer(mLibVLC);
mVideoLayout = findViewById(R.id.video_layout);
}
@Override protected void onDestroy() { super.onDestroy(); mMediaPlayer.release(); mLibVLC.release(); }
@Override protected void onStart() { super.onStart();
mMediaPlayer.attachViews(mVideoLayout, null, ENABLE_SUBTITLES, USE_TEXTURE_VIEW); final Media media = new Media(mLibVLC, Uri.parse(mRemoteUrl)); mMediaPlayer.setMedia(media); media.release(); mMediaPlayer.play(); }
@Override protected void onStop() { super.onStop();
mMediaPlayer.stop(); mMediaPlayer.detachViews(); }}
复制代码
划线
评论
复制
发布于: 2 小时前
版权声明: 本文为 InfoQ 作者【Changing Lin】的原创文章。
原文链接:【http://xie.infoq.cn/article/e8cd89a39d1741615b84899e0】。文章转载请联系作者。
Changing Lin
关注
获得机遇的手段远超于固有常规之上~ 2020.04.29 加入
我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。











评论