欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

android 使用 IJKPlayer 播放視頻流的實(shí)現(xiàn)代碼

 更新時(shí)間:2021年11月24日 14:58:20   作者:右手的鼠標(biāo)  
這篇文章主要介紹了android 使用 IJKPlayer 播放視頻流,這需要借助 IAndroidIO 這個(gè)接口,也可以用于播放本地文件,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

最近在做音視頻相關(guān)的內(nèi)容,這就無法避開視屏采集和播放的問題了,然后播放器使用的是 ijkplayer,這個(gè)東西使用 url 播放倒是沒啥問題,只是我們的方案是接收 flv 的視頻流進(jìn)行播放,這需要借助 IAndroidIO 這個(gè)接口,也可以用于播放本地文件。

實(shí)現(xiàn) IAndroidIO 接口

播放類的實(shí)現(xiàn)

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>()  // 內(nèi)存隊(duì)列,用于緩存獲取到的流數(shù)據(jù),要實(shí)現(xiàn)追幀效果,只需要根據(jù)策略丟棄本地緩存的內(nèi)容即可

    private fun takeFirstWithLen(len : Int): ByteArray {  // 取 byte 數(shù)據(jù)用于界面渲染
        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)
    }

	// 如果是播放本地文件,可在此處打開文件流,后續(xù)讀取文件流即可
    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) // 阻塞式讀取,沒有數(shù)據(jù)不渲染畫面
        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
    }
}

調(diào)用播放類

接下來,就看看如何調(diào)用播放實(shí)例了。注意:我們還是需要傳入一個(gè) url,只是這個(gè) 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 實(shí)例再做播放
        }
    }
    @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"); // 屬性設(shè)置支持,轉(zhuǎn)入我們自定義的播放類

        player.setSurface(this.surface);
        player.setAndroidIOCallback(ReadByteIO.Companion.getInstance());

        Uri uri = Uri.parse("ijkio:androidio:" + ReadByteIO.Companion.getURL_SUFFIX()); // 設(shè)定我們自定義的 url
        try {
            player.setDataSource(uri.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        player.prepareAsync();
        player.start();
    }
}

到此這篇關(guān)于android 使用 IJKPlayer 播放視頻流的文章就介紹到這了,更多相關(guān)android 播放視頻流內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論