概述
最近在做音视频相关的内容,这就无法避开视屏采集和播放的问题了,然后播放器使用的是 ijkplayer,这个东西使用 url 播放倒是没啥问题,只是我们的方案是接收 flv 的视频流进行播放,这需要借助 IAndroidIO 这个接口,也可以用于播放本地文件。
实现 IAndroidIO 接口
播放类的实现
class ReadByteIO private constructor(): IAndroidIO { companion object { private var instance: ReadByteIO? = null var URL_SUFFIX = "recv_data_online" @Synchronized fun getInstance(): ReadByteIO { // 单例 instance?.let { return it } instance = ReadByteIO() return instance!! } } private var TAG = ReadByteIO::class.java.simpleName private var flvData = LinkedBlockingDeque<Byte>() // 内存队列,用于缓存获取到的流数据,要实现追帧效果,只需要根据策略丢弃本地缓存的内容即可 private fun takeFirstWithLen(len : Int): ByteArray { // 取 byte 数据用于界面渲染 var byteList = ByteArray(len) for (i in 0 until len) { byteList[i] = flvData.take() } return byteList } @Synchronized fun addLast(bytes: ByteArray): Boolean { var tmpList:List<Byte> = bytes.toList() Log.e(TAG, "tmpList size " + tmpList.size) return flvData.addAll(tmpList) } // 如果是播放本地文件,可在此处打开文件流,后续读取文件流即可 override fun open(url: String?): Int { if (url == URL_SUFFIX) { return 1 // 打开播放流成功 } return -1 // 打开播放流失败 } override fun read(buffer: ByteArray?, size: Int): Int { var tmpBytes = takeFirstWithLen(size) // 阻塞式读取,没有数据不渲染画面 System.arraycopy(tmpBytes, 0, buffer, 0, size) return size } override fun seek(offset: Long, whence: Int): Long { return 0 } override fun close(): Int { return 0 } }
调用播放类
接下来,就看看如何调用播放实例了。注意:我们还是需要传入一个 url,只是这个 url 是我们自定义的
public class RecordVideoActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener { private String TAG = RecordVideoActivity.class.getSimpleName(); private IjkMediaPlayer player; private Surface surface; private TextureView playView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_record_video); playView = findViewById(R.id.v_play); playView.setSurfaceTextureListener(this); } @Override protected void onDestroy() { super.onDestroy(); if (player != null) { player.stop(); } } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { if (surface != null) { this.surface = new Surface(surface); play(); // 存在 surface 实例再做播放 } } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {return false; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } private void play() { player = new IjkMediaPlayer(); player.reset(); player.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzemaxduration", 100); player.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 25 * 1024); player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0); player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1); player.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "threads", 1); player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "sync-av-start", 0); player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec",1); player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1); player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1); player.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "protocol_whitelist", "ijkio,crypto,file,http,https,tcp,tls,udp"); // 属性设置支持,转入我们自定义的播放类 player.setSurface(this.surface); player.setAndroidIOCallback(ReadByteIO.Companion.getInstance()); Uri uri = Uri.parse("ijkio:androidio:" + ReadByteIO.Companion.getURL_SUFFIX()); // 设定我们自定义的 url try { player.setDataSource(uri.toString()); } catch (IOException e) { e.printStackTrace(); } player.prepareAsync(); player.start(); } }
到此这篇关于android 使用 IJKPlayer 播放视频流的文章就介绍到这了,更多相关android 播放视频流内容请搜索靠谱客以前的文章或继续浏览下面的相关文章希望大家以后多多支持靠谱客!
最后
以上就是愤怒含羞草为你收集整理的android 使用 IJKPlayer 播放视频流的实现代码的全部内容,希望文章能够帮你解决android 使用 IJKPlayer 播放视频流的实现代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复