目前公司所开发的app是用了ExoPlayer 和 IjkPlayer 两款播放器来回切换播放视频流的,有切换音轨的功能需求,所以就写了这篇博客。

首先是IjkPlayer切换音轨和内嵌字幕的方式:

我使用的IjkPlayer是0.8.8

  if (ijkVideoView != null && ijkVideoView.isPlaying()) { // 判断播放器ITrackInfo[] mIjkTrackInfo = ijkVideoView.getTrackInfo(); //这里可以获得所有的轨道信息for (int i = 0; i < mIjkTrackInfo.length; i++) {ITrackInfo trackInfo = mIjkTrackInfo[i];if (trackInfo.getTrackType() == ITrackInfo.MEDIA_TRACK_TYPE_AUDIO) { //判断是否是音轨信息Log.d("checkAudio: ", trackInfo.getInfoInline());} else if (trackInfo.getTrackType() == ITrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) { //判断是否是内嵌字幕信息Log.d("checkSubTitle: ", trackInfo.getInfoInline());}}}

上面的方法就可以获取到视频的所有轨道信息,我用了测试的视频打印Log出来是这样的:

checkAudio:: AUDIO, aac, N/A, 44100 Hz, fre
checkAudio:: AUDIO, aac, N/A, 44100 Hz, eng
checkSubTitle:: TIMEDTEXT, eng
checkSubTitle:: TIMEDTEXT, spa

接下来就可以使用IjkPlayer自带的selectTrack方法来切换音轨和字幕了,传递的是一个下标。

注:IjkPlayer默认是关闭字幕显示的使用以下代码配置可以显示视频字幕

 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "subtitle", 1);

还有一个问题就是IjkPlayer切换完音轨或者字幕,会快动作播放或者音画不同步几秒,应该是播放器需要去处理音频和视频的时间戳,但是给客户的体验不是很好。

于是我就先让播放器暂停,保存当前进度,切换音轨,跳转到保存的进度继续播放就不会出现音画不同步的问题了,也算是投机取巧了。

                                    ijkVideoView.pause();videoView.postDelayed(new Runnable() {@Overridepublic void run() {int progress = mediaControllerView.getCurProgress();ijkVideoView.selectTrack(stream);ijkVideoView.seekTo(progress);ijkVideoView.start();}}, 500);

接下来就是ExoPlayer切换音轨和字幕的方式了:

我使用的ExoPlayer版本是2.13.2,相比IjkPlayer切换音轨的方式,ExoPlayer播放器切换感觉复杂好多,也可能是我本人技术不行,觉得ExoPlayer代码搞的乱七八糟的,没有IjkPlayer好用。

首先就是获取视频的轨道信息:

                MappingTrackSelector.MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();if (mappedTrackInfo != null) {for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(i);if (C.TRACK_TYPE_AUDIO == mappedTrackInfo.getRendererType(i)) { //判断是否是音轨for (int groupIndex = 0; groupIndex < rendererTrackGroups.length; groupIndex++) {TrackGroup trackGroup = rendererTrackGroups.get(groupIndex);Log.d("checkAudio", trackGroup.getFormat(0).toString());}} else if (C.TRACK_TYPE_TEXT == mappedTrackInfo.getRendererType(i)) { //判断是否是字幕for (int groupIndex = 0; groupIndex < rendererTrackGroups.length; groupIndex++) {TrackGroup trackGroup = rendererTrackGroups.get(groupIndex);Log.d("checkSubTitle", trackGroup.getFormat(0).toString());}}}}

大致上和IjkPlayer播放器获取的方式差不多,日志打印是这样的:

checkAudio: Format(2, Stereo, null, audio/mp4a-latm, mp4a.40.2, -1, fr, [-1, -1, -1.0], [2, 44100])
checkAudio: Format(3, Stereo, null, audio/mp4a-latm, mp4a.40.2, -1, en, [-1, -1, -1.0], [2, 44100])
checkSubTitle: Format(4, null, null, text/x-ssa, null, -1, en, [-1, -1, -1.0], [-1, -1])
checkSubTitle: Format(5, null, null, text/x-ssa, null, -1, es, [-1, -1, -1.0], [-1, -1])

接下来就是切换,ExoPlayer传递的不是一个下标,而是使用TrackSelector 配置注入。

        trackSelector.setParameters(trackSelector.getParameters().buildUpon().setPreferredTextLanguage(preferredTextLanguage) //这个方法就是字幕轨道.setPreferredAudioLanguage(preferredAudioLanguage)); //这个方法是音轨

上面的方法可以配置音轨和字幕可以传递空字符串,用的是轨道的lauguage字段的名字。

trackGroup.getFormat(0).language;

这样就大功告成啦!

本人最近初学音视频开发也是个萌新,有技术交流的可以添加QQ:760082774

ExoPlayer 和 IjkPlayer 切换音轨和内嵌字幕的方法。相关推荐

  1. 去除rmvb内嵌字幕的方法

    不少朋友喜欢通过看日剧.看动漫的方式练习听力,但目前网上流传得大多是已内嵌中文字幕的版本.可能因人而异,中文字幕或多或少会对听力的练习过程有所影响.那么如何去掉rmvb中的内嵌字幕呢? 利用软件:TM ...

  2. 解决内嵌字幕的MKV视频剪辑分割时,字幕无法伴随子视频片段的问题

    问题描述 剪辑分割一个MKV格式的视频,内嵌字幕,分割后字幕无法伴随子视频片段,加载不到字幕,字幕消失. 常用的格式工厂.视频软件王.视频编辑专家等一些列傻瓜视频剪辑软件等都没有效果. 解决方案 使用 ...

  3. 去除RMVB的内嵌字幕方法

    最近在网上看到一个用KMPlayer替换rmvb视频内嵌字幕的解决办法,转过来,也算一个比较实用的小技巧,呵呵~~~~~~~~~~~     用KMPlayer替换rmvb视频内嵌字幕的解决办法 完美 ...

  4. android之在view中内嵌浏览器的方法

    我要做的一个东西是在一个页面的中间嵌入浏览器,一开始不知道从哪里开始,因为以前用的都是Textveiw或者editVeiw之类的控件,而它们并不能用来显示网页的内容,怎么办呢? 首先想到的是:是不是有 ...

  5. python 视频硬字幕提取 内嵌字幕提取工具

    项目简介 Video-subtitle-extractor (vse) 是一款将视频中的硬字幕提取为外挂字幕文件(srt格式)的软件. 主要实现了以下功能: 提取视频中的关键帧 检测视频帧中文本的所在 ...

  6. 在docker容器里,ffmpeg给视频文件内嵌字幕文件,不生效,如何解决?

    用ffmpeg命令,发现执行成功,但视频文件就是没有字幕.看不出问题出现在什么地方.后来直接用ffmpeg添加水印命令测试,发现是缺少字体文件,如下图所示: 报Fontconfig error: Ca ...

  7. selenium登录斗鱼tv(切换iframe内嵌页面)

    from selenium.webdriver import Chrome import time# 1.下载selenium # 2.将驱动放在python解释器文件夹中web = Chrome() ...

  8. GNU C内嵌汇编学习笔记

    前文所述,只是针对汇编格式的整理,本文将使用coreboot项目代码对其进行实例化.以方便.清晰了解到如何在C语言里使用内嵌汇编的方法.同样地,网络上也有众多文章涉及到这方面,所以本文更多是归纳总结. ...

  9. Go语言学习 二十一 内嵌

    本文最初发表在我的个人博客,查看原文,获得更好的阅读体验 在像Java这种语言中,有子类(或者继承)的概念,通过继承复用已有的功能或属性,与继承不同,Go中使用组合的方式来完成已有实现的复用,这种做法 ...

最新文章

  1. 创建 Web 部件页--msdn
  2. JOGL   java调用openGL
  3. ASP.NET CORE之上传文件夹
  4. MATLAB常用命令、函数与运算
  5. Java还能热多久?学Java有前途吗?
  6. python多线程并行编程_Python并行编程(二):基于线程的并行
  7. salad--8||9
  8. 健忘族的大爱,机器人管家Watch Bot提醒你不要丢三落四
  9. react --- 生命周期 给子组件传递数据
  10. 【收集】常用的cmd命令
  11. 白银T+D [Ag(T+D)]业务介绍
  12. es创建索引设置字段不分词_java整合es指定字段不分词搜索
  13. 爱情六十三课,定个开放日
  14. [JS基础] 之类型判断
  15. Android音量设置流程干货版
  16. 优质前端掘金小册推荐及优惠购买链接
  17. ZOC7 for Mac破解版激活方法附注册码
  18. cad补全三视图_机械制图课程中补全三视图的解题方法
  19. 移动Web开发字体格式选择(附.woff\.woff2 兼容性)
  20. mac10.9下eclipse的storm开发环境搭建

热门文章

  1. word中如何手工快速对齐目录
  2. Dependency Check的实战应用
  3. IAR for ARM、MSP430、8051 保姆式安装教程 (附IAR for ARM、MSP430、8051安装包和工程源码)
  4. 考研成绩公布了,分享一下自己曾经走过的那些坑
  5. 便签存储在哪个文件夹,Windows 7便笺保存位置
  6. OB1203传感器的应用(一)
  7. php 递归 返回,php递归函数返回值返回不出的问题
  8. 如何将IIS6服务器的网站批量迁移到IIS7中
  9. 区块链助力跨省、零材料办理 成都武侯打造“中国政务服务第一链”
  10. m4v如何转换成mp4,只需这几步即可