android 使用 IJKPlayer 播放视频流的实现代码

最近在做音视频相关的内容,这就无法避开视屏采集和播放的问题了,然后播放器使用的是 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 播放视频流内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • android studio集成ijkplayer的示例代码

    介绍 ijkplayer是一款非常火的开源视频播放器,android和IOS通用.关于怎么编译怎么导入android Studio中自己的项目,其中坑很多,本篇记录下自己的操作记录.ijkplayer现在的版本是0.8.3,当然是使用最新的版本集成了. 编译ijkplayer 关于编译,我是在Ubuntu上编译后拷贝到win10中的,ijkplayer源码需要gcc编译,windows各种不好用,如果使用cynwin还不如在ubuntu下编译. 编译的过程是下载sdk,ndk.设置环境变量后按照

  • 在ubuntu下编译ijkplayer-android的方法

    我前面一片文字讲的是在windows的cygwin中去编译,那真是各种坑啊,软链接无法识别,x86和86_64的so文件无法编译出来等等,我折腾了几天还是没有在cygwin中完美编译ijkplayer,今天我用了一下同事的ubuntu的电脑,变异ijkplayer-android真的是很快,很快的. 1.前提: 下面是官方的提示: # install homebrew, git, yasm ruby -e "$(curl -fsSL https://raw.githubusercontent.c

  • 基于Android引入IjkPlayer无法播放mkv格式视频的解决方法

    写在前面 项目中直接引用或者直接编译源码得到的ijkplayer在播放mkv文件时出现(-10000)的错误,去项目github查看了才知道,默认是不支持mkv和rmvb格式视频的播放的. 用了一天时间解决(为什么用了一天,因为我蠢啊),这里记录一下解决的方法(官方上面其实已经有了详细的教程,无奈我当时没有很认真看.)这里为我自己这个新手做个记录: 仍然是采用编译源码的方式引入,只是需要按照官方的方法更改一下脚本文件 ijkplayer官方地址:https://github.com/Bilibi

  • Android ijkplayer的使用方法解析

    ijkplayer是Bilibili基于ffmpeg开发并开源的轻量级视频播放器,支持播放本地网络视频,也支持流媒体播放.支持Android&iOS. ijkplayer的编译这里不多阐述,我也是直接获取别人编译完成的so库文件,直接使用的.如果你对ijkplayer的编译感兴趣,可以百度一下,有很多文章. 使用ijkplayer 导包 ijkplayer源码官方下载地址:https://github.com/Bilibili/ijkplayer 上面是官方提供的ijkplayer的源码地址,但

  • Android基于IJKPlayer视频播放器简单封装设计

    播放器的简单设计 播放器基于IJKPlayer来设计的, 播放器大致分三层 1.播放内核(基于ijkMediaplayer) 2.播放器View 3.播放器的MediaController 1.封装播放内核 我们都知道需要播放一个视频需要三个过程 1.create MediaPlayer 2.MediaPlayer prepare 3.MediaPlayer 与 Surface 绑定 xinvideoplayer中使用了VideoManager来控制ijkmediaplayer 所有的操作 三个

  • android 使用 IJKPlayer 播放视频流的实现代码

    最近在做音视频相关的内容,这就无法避开视屏采集和播放的问题了,然后播放器使用的是 ijkplayer,这个东西使用 url 播放倒是没啥问题,只是我们的方案是接收 flv 的视频流进行播放,这需要借助 IAndroidIO 这个接口,也可以用于播放本地文件. 实现 IAndroidIO 接口 播放类的实现 class ReadByteIO private constructor(): IAndroidIO { companion object { private var instance: Re

  • Android使用SoundPool播放音效

    本文实例为大家分享了Android使用SoundPool播放音效的具体代码,供大家参考,具体内容如下 SoundPool(int maxStreams, int streamType, int srcQuality) 参数依次是: ①指定支持多少个声音,SoundPool对象中允许同时存在的最大流的数量. ②指定声音类型,流类型可以分为STREAM_VOICE_CALL(通话), STREAM_SYSTEM(系统), STREAM_RING(铃声),STREAM_MUSIC(媒体音量) 和STR

  • android surfaceView实现播放视频功能

    本文实例为大家分享了android surfaceView实现播放视频的具体代码,供大家参考,具体内容如下 RelativeLayout <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.an

  • Android简易音乐播放器实现代码

    本文实例为大家分享了Android音乐播放器的具体代码,供大家参考,具体内容如下 1.播放项目内的音乐 package com.thm.g150820_android26_playmusic; import Android.media.MediaPlayer; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.wid

  • Android实现直接播放麦克风采集到的声音

    本文实例讲述了Android实现直接播放麦克风采集到的声音.分享给大家供大家参考.具体如下: 这是一个直接播放麦克风采集到的声音线程类: class RecordThread extends Thread{ static final int frequency = 44100; static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; static final int audioEncoding

  • Android使用WebView播放flash的方法

    本文实例讲述了Android使用WebView播放flash及判断是否安装flash插件的方法.分享给大家供大家参考.具体实现方法如下: 一.问题: 最近帮一个同学做一个项目,断断续续的一些知识点记录一下.一个页面中有一个WebView,用来播放swf,如果系统中未安装flash插件,必须提示用户到market中安装. 二.解决方法: 下面做一个demo,效果图如下: 图1: 图2: 图3: 首先布局文件,很简单: 复制代码 代码如下: <RelativeLayout xmlns:android

  • Android编程实现播放音频的方法示例

    本文实例讲述了Android编程实现播放音频的方法.分享给大家供大家参考,具体如下: 在 Android 中播放音频文件一般都是使用 MediaPlayer 类来实现的,它对多种格式的音 频文件提供了非常全面的控制方法,从而使得播放音乐的工作变得十分简单.下表列出了 MediaPlayer 类中一些较为常用的控制方法. 方法名 功能描述 setDataSource() 设置要播放的音频文件的位置. prepare() 在开始播放之前调用这个方法完成准备工作. start() 开始或继续播放音频.

  • Android DragVideo实现播放视频时任意拖拽的方法

    Android DragVideo实现播放视频时任意拖拽 DragVideo A Method to Drag the Video When Playing Video 一种在播放视频时,能够拖拽的方案 为什么有这个工程 经常在爱奇艺网站上看电影,看到如果滑动掩盖了播放窗口后,就后在最下面有一个小播放界面.并且这个播放界面,是可以任意拖拽的.感觉很酷 既然web端能实现,就想了想在移动端设备上,是否也能实现这个效果,于是就有了- 效果图: ------> 实现思路:1.播放视频的view选择Te

  • Android使用VideoView播放本地视频和网络视频的方法

    1.效果展示 2.布局文件 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="matc

随机推荐