这篇文章主要介绍了android使用IJKPlayer播放视频流,这需要借助IAndroidIO这个接口,也可以用于播放本地文件,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
最近在做音视频相关的内容,这就无法避开视屏采集和播放的问题了,然后播放器使用的是 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 播放视频流的实现代码
基础教程推荐
猜你喜欢
- iOS开发 全机型适配解决方法 2023-01-14
- Android Compose自定义TextField实现自定义的输入框 2023-05-13
- IOS获取系统相册中照片的示例代码 2023-01-03
- iOS开发使用XML解析网络数据 2022-11-12
- iOS中如何判断当前网络环境是2G/3G/4G/5G/WiFi 2023-06-18
- Android开发Compose集成高德地图实例 2023-06-15
- iOS Crash常规跟踪方法及Bugly集成运用详细介绍 2023-01-18
- Flutter进阶之实现动画效果(三) 2022-10-28
- Android实现短信验证码输入框 2023-04-29
- MVVMLight项目Model View结构及全局视图模型注入器 2023-05-07