写点什么

一种播放远程 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 小时前
用户头像

Changing Lin

关注

获得机遇的手段远超于固有常规之上~ 2020.04.29 加入

我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。

评论

发布
暂无评论
一种播放远程TS格式媒体文件的新方案