当前位置:网站首页>ffplay实现自定义输入流播放
ffplay实现自定义输入流播放
2022-06-23 05:06:00 【CodeOfCC】
文章目录
前言
使用ffplay播放视频,有时我们只能获取到byte数据,比如Windows的嵌入资源只能拿到在内存中的视频文件数据,或者是自定义协议网络传输的视频,这个时候我们就需要实现一个流数据输入接口来进行播放了,ffmpeg的AVIOContext就支持这一功能,我们只需要对ffplay进行简单的拓展即可。
一、如何使用AVIOContext?
avio是ffmpeg自定义输入流的对象,它是AVformatContext的一个字段,我只需要创建avio对象并实现其回调方法,然后给AVformatContext.pb赋值即可。
1、定义回调方法
以文件流为例(省略了打开文件和获取文件长度的操作)
FILE* file;
static int avio_read(ACPlay play, uint8_t* buf, int bufsize)
{
return fread(buf, 1, bufsize, file);
}
static int64_t avio_seek(ACPlay play, int64_t offset, int whence)
{
switch (whence)
{
case AVSEEK_SIZE:
return fileSize;
break;
case SEEK_CUR:
fseek(file, offset, whence);
break;
case SEEK_SET:
fseek(file, offset, whence);
break;
case SEEK_END:
fseek(file, offset, whence);
break;
default:
break;
}
return ftell(test3file);
}
2、关联AVFormatContext
AVFormatContext* ic = NULL;
AVIOContext* avio = avio_alloc_context((unsigned char*)av_malloc(1024 * 1024), 1024 * 1024, 0, s, avio_read, NULL, avio_seek);
if (avio)
{
ic->pb = avio;
ic->flags = AVFMT_FLAG_CUSTOM_IO;
}
avformat_open_input(&ic, "", NULL, NULL);
3、销毁资源
if (ic->avio)
{
if (ic->avio->buffer)
{
av_free(is->avio->buffer);
}
avio_context_free(&is->avio);
ic->avio = NULL;
}
二、ffplay中使用AVIOContext
1、添加字段
在VideoState中添加如下字段
AVIOContext* avio;
2、定义接口
/// <summary>
/// 开始播放
/// </summary>
/// <param name="play">播放器对象</param>
/// <param name="read">自定义输入流,读取数据时的回调</param>
/// <param name="seek">自定义输入流,定位时的回调</param>
void ac_play_startViaCustomStream(ACPlay play, ACPlayCustomPacketReadCallback read, ACPlayCustomPacketStreamSeekCallback seek);
{
VideoState* s = (VideoState*)play;
if(read)
s->avio = avio_alloc_context((unsigned char*)av_malloc(1024 * 1024), 1024 * 1024, 0, s, read, NULL, seek);
stream_open(s, "", NULL);
}
3、关联AVFormatContext
在read_thread中avformat_open_input的上一行添加如下代码:
if (is->avio)
{
ic->pb = is->avio;
ic->flags = AVFMT_FLAG_CUSTOM_IO;
}
4、销毁资源
在stream_close中添加如下代码
if (ic->avio)
{
if (ic->avio->buffer)
{
av_free(is->avio->buffer);
}
avio_context_free(&is->avio);
ic->avio = NULL;
}
总结
以上就是今天要讲的内容,之所以去实现这样的功能是因为笔者曾经工作中,遇到过相关使用场景,在程序启动时播放mp4嵌入资源,将其读取出来保存文件在播放显然不是很好的方案,而且ffmpeg本身支持自定义输入流,所以很容易就将此功能添加到ffplay上了。总的来说,这个功能有一定的使用场景而且实现也不算复杂。
边栏推荐
- 云盒子联合深信服,为南京一中打造智慧双模教学资源分享平台
- [focus on growth and build a dream for the future] - TDP year-end event, three chapters go to the Spring Festival!
- Day_05 传智健康项目-预约管理-预约设置
- Leetcode topic resolution valid Sudoku
- Progress of layer 2 technical scheme
- 开源生态|超实用开源License基础知识扫盲帖(下)
- How to add libraries for Arduino ide installation
- Illustration Google V8 18: asynchronous programming (I): how does V8 implement micro tasks?
- Long substring without repeating characters for leetcode topic resolution
- I heard you want to embed ppt on WordPress website?
猜你喜欢

Day_ 11 smart communication health project - graphic report and poi Report

(1)基础学习——vim编辑器常用快捷操作命令

Machine learning 3-ridge regression, Lasso, variable selection technique

Day_ 02 smart communication health project - appointment management - inspection item management

sklearn sklearn中的模型调参利器 gridSearchCV(网格搜索)

Day_02 传智健康项目-预约管理-检查项管理

机器学习3-岭回归,Lasso,变量选择技术

Gplearn appears assignment destination is read only

Vs+qt project transferred to QT Creator

索引——MySQL
随机推荐
[focus on growth and build a dream for the future] - TDP year-end event, three chapters go to the Spring Festival!
How to add libraries for Arduino ide installation
What is a PDCA cycle? How to integrate PDCA cycle and OKR
CVE-2021-20038
Extend your kubernetes API using the aggregation API
又到半年总结时,IT人只想躺平
bootstrap如何清除浮动的样式
熟练利用切片操作
Microsoft interview question: creases in origami printing
Day_10 传智健康项目-权限控制、图形报表
Laravel log channel 分组配置
图解 Google V8 # 17:消息队列:V8是怎么实现回调函数的?
qt creater搭建osgearth环境(osgQT MSVC2017)
A review: neural oscillation and brain stimulation in Alzheimer's disease
Day_11 传智健康项目-图形报表、POI报表
mysql读已提交和可重复度区别
Day_ 11 smart communication health project - graphic report and poi Report
Possible pits in mongodb project
云盒子联合深信服,为南京一中打造智慧双模教学资源分享平台
Day_ 12 smart health project jasperreports