【obs-studio开源项目从入门到放弃】obs媒体源 ffmpeg_source 分析


前言

obs支持添加各种容器格式的视频文件,音频文件(mp4、flv、mp3、ts),也支持添加网络流(rtmp,srt,rtsp,udp)。本质上obs是基于ffmpeg的libavformat库提供解码能力播放媒体视频。只要是obs的依赖ffmpeg库支持的协议都可以作为媒体源添加。
通过下面命令查看ffmpeg支持的协议

.\ffmpeg.exe -protocols		//打印ffmpeg支持的协议

媒体源的创建

媒体源的创建有多种方式,可以直接将视频文件直接拖拽进obs主窗口,可以在主窗口右键添加媒体源,也可以复制当前存在的媒体源。不管哪种方式创建媒体源最后的入口都是obs_source_create,这是libobs提供的创建源的api,如果进行obs二次开发添加源的入口也都是走这个api。下面贴一下拖拽方式创建媒体源的调用堆栈。

>	obs-ffmpeg.dll!ffmpeg_source_update(void * data, obs_data * settings)456	C
 	obs-ffmpeg.dll!ffmpeg_source_create(obs_data * settings, obs_source * source)613	C
 	obs.dll!obs_source_create_internal(const char * id, const char * name, obs_data * settings, obs_data * hotkey_data, bool private, unsigned int last_obs_ver)387	C
 	obs.dll!obs_source_create(const char * id, const char * name, obs_data * settings, obs_data * hotkey_data)416	C
 	obs64.exe!OBSBasic::AddDropSource(const char * data, OBSBasic::DropType image)176	C++
 	obs64.exe!OBSBasic::dropEvent(QDropEvent * event)280	C++
 	[外部代码]	
 	obs64.exe!run_program(std::basic_fstream<char,std::char_traits<char>> & logFile, int argc, char * * argv)2143	C++
 	obs64.exe!main(int argc, char * * argv)2839	C++
 	obs64.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal)97	C++

媒体源输出音频帧和视频帧

media-playback 封装了操作媒体源的api

obs对媒体源的操作都封装到了media-playback.lib,通过media.h里的函数的命名就可以看出。

//媒体源的初始化和销毁
extern bool mp_media_init(mp_media_t *media, const struct mp_media_info *info);
extern void mp_media_free(mp_media_t *media);

//媒体源的控制 播放 停止 暂停 获取当前播放时间 快进快退
extern void mp_media_play(mp_media_t *media, bool loop, bool reconnecting);
extern void mp_media_stop(mp_media_t *media);
extern void mp_media_play_pause(mp_media_t *media, bool pause);
extern int64_t mp_get_current_time(mp_media_t *m);
extern void mp_media_seek_to(mp_media_t *m, int64_t pos);

通过下面创建媒体源的调用堆栈可以看到,最终都调用到了media-playback的里面。

 	obs-ffmpeg.dll!mp_media_init_internal(mp_media * m, const mp_media_info * info)797	C
 	obs-ffmpeg.dll!mp_media_init(mp_media * media, const mp_media_info * info)834	C
 	obs-ffmpeg.dll!ffmpeg_source_open(ffmpeg_source * s)319	C
 	obs-ffmpeg.dll!ffmpeg_source_update(void * data, obs_data * settings)453	C
 	obs-ffmpeg.dll!ffmpeg_source_create(obs_data * settings, obs_source * source)613	C

一图抵千言,贴一下我准备的xmind截图。
media-playback
可以看到在mp_media_init_internal函数里面创建了一个mp_media_thread_start线程来执行音视频的解码,对ffmpeg解封装流程比较熟悉,这里面的代码就很好理解了,这里便不再赘述。有时间单独做一个ffmpeg系列的专栏,详细说一下ffmpeg解封装,编解码的api调用逻辑。

mp_media_next_video() 输出解码后的视频帧

解码后的视频帧通过函数mp_media_next_video调用在ffmpeg_source_open里面绑定回调函数get_audio,最终通过 obs_source_output_video() 插入到libobs的视频帧缓存队列,等待视频渲染线程取走做渲染。媒体源属于异步输出视频帧,output_flags包含OBS_SOURCE_ASYNC_VIDEO属性。

static void get_frame(void *opaque, struct obs_source_frame *f)
{
	struct ffmpeg_source *s = opaque;
	obs_source_output_video(s->source, f);
}

mp_media_next_audio() 输出解码后的音频帧

解码后的音频帧通过函数 mp_media_next_audio() 调用在ffmpeg_source_open里面绑定回调函数get_audio,最终通过obs_source_output_audio输出到libobs的音频帧缓冲队列,等待音频编码线程取走做编码发送。

static void get_audio(void *opaque, struct obs_source_audio *a)
{
	struct ffmpeg_source *s = opaque;
	obs_source_output_audio(s->source, a);

	if (!s->is_local_file && os_atomic_set_bool(&s->reconnecting, false))
		FF_BLOG(LOG_INFO, "Reconnected.");
}

媒体源的控制

控制媒体源的暂停,播放,还有seek操作都比较简单。阅读下面绑定的函数很容易理解。

struct obs_source_info ffmpeg_source = {
	.media_play_pause = ffmpeg_source_play_pause,	//控制暂停
	.media_restart = ffmpeg_source_restart,			//重新播放
	.media_stop = ffmpeg_source_stop,				//停止播放
	.media_get_duration = ffmpeg_source_get_duration,//获取播放媒体源的总时长
	.media_get_time = ffmpeg_source_get_time,		//获取当前播放时机
	.media_set_time = ffmpeg_source_set_time,		// seek操作
	.media_get_state = ffmpeg_source_get_state,		//获取当前播放状态
}

总结

obs的媒体源整个处理比较简单,底层基于ffmpeg的api做视频的解封装,只用了一个线程完成了音视频的解码输出,解码完成后通过libobs的api添加到音视频相应的队列,等待音视频各自的线程取走渲染播放。media-playback是一个非常好的可以学习ffmepg解封装api的一个小项目。

以上都是个人工作当中对obs-studio开源项目的理解,难免有错误的地方,如果有欢迎指出。

若有帮助幸甚。


技术参考

  1. 视频技术参考: https://ke.qq.com/course/3202131?flowToken=1040950
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OBS Studio是一款开的跨平台视频录制和实时流媒体软件。它可以用于录制电脑屏幕和摄像头视频,并支持多种特效和过滤器。使用OBS Studio进行录制和实时流媒体需要进行一些设置和安装插件。首先,您可以通过官方支持的自动化编译脚本来编译OBS Studio,这大大降低了编译的门槛。另外,您还可以使用OBS的插件来实现一些高级功能,比如RTSP服务。安装OBS Studio和插件后,您可以根据需要设置录制文件的存放路径和添加所需的来,然后开始录制。录制完成后,您可以通过菜单选项打开录像文件或直接打开录制文件的存放路径来查看录制的视频。123 #### 引用[.reference_title] - *1* [【obs-studio开源项目入门放弃obs-studio项目简介和架构](https://blog.csdn.net/qq_33844311/article/details/121479224)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *2* [使用OBS-Studio软件推流直播教程,支持RTMP及RTSP两种协议](https://blog.csdn.net/bacawa/article/details/128450429)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *3* [OBS Studio录屏软件安装和使用教程](https://blog.csdn.net/qq_40910781/article/details/124108272)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值