当前位置:首页 » 《随便一记》 » 正文

android 使用 IJKPlayer 播放视频流_右手的鼠标

24 人参与  2022年05月05日 09:10  分类 : 《随便一记》  评论

点击全文阅读


最近在做音视频相关的内容,这就无法避开视屏采集和播放的问题了,然后播放器使用的是 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();
    }
}

点击全文阅读


本文链接:http://zhangshiyu.com/post/39504.html

播放  自定义  用于  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 老公为女助理将我开除,却骂我小肚鸡肠限时免费***章节速览_苏豪顾霞老公小说无删减版在线免费阅读
  • 考古遇险,未婚夫只想救青梅精彩章节试读_江天罗莹青梅关键剧情节选解锁
  • 才下眉头,却上心头后续在线(江蓠祈宸)_才下眉头,却上心头后续在线(江蓠祈宸)
  • 诱她,矜娇太子爷拿命宠!限时免费***章节速览_「顾青柠墨瑾川」爆款小说高能章节试读
  • [绑定好孕系统后,我杀疯了]最新章节在线阅读_「向阳陶倩晶晶」章节免费试读
  • (春到南楼雪尽处全书+后续)(苏枝夏傅庭州)_春到南楼雪尽处全书+后续列表_笔趣阁苏枝夏傅庭州
  • (番外)+(全书)温洛梨霍韫年(何处繁花醒洛梨结局+番外)_温洛梨霍韫年免费列表_笔趣阁(何处繁花醒洛梨结局+番外)
  • 时光不过大梦一场全文在线阅读_[江时宜傅临川]完结版免费在线阅读
  • 「我是男主的白月光」小说章节免费试读_[谢淮舟渺渺景平王]章节彩蛋限时释出‌
  • 我在眷恋里无路可逃+后续+完结(季微澜苏逸尘)全书免费_(季微澜苏逸尘)我在眷恋里无路可逃+后续+完结后续(季微澜苏逸尘)
  • 用我的情感交易我失忆他却疯了+后续+结局(妙妙傅沉玉姜月)列表_用我的情感交易我失忆他却疯了+后续+结局(妙妙傅沉玉姜月)用我的情感交易我失忆他却疯了+后续+结局在线
  • (番外)+(全书)余烬终成灰全书+后续(江晚照傅青辞)完结_(江晚照傅青辞)列表_笔趣阁(余烬终成灰全书+后续)

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1