调教 GPT 实现多流合一定时轮播
昨天接到一个需求,要实现4-6路流合一,做定时切换的需求,由于没有现成的云导播台,于是首先想到使用 FFMPEG 命令实现。
由于需要添加台标、背景音乐之的类,各种 Filter 写到手软,第一时间想偷懒,就想用GPT 协助实现。
我用的是白嫖 GPT 3.5,Prompt 是 `我有3路直播流,分别是rtmp://x/sz-live/20230615-s01, rtmp://x/sz-live/20230615-s02, rtmp://x/sz-live/20230615-s03
我想将这3路流合并成一路流,按30秒的时间进行切换输出,请给我一个命令
GPT 飞快的给出了一系列命令,经过几个回合的调教,最终 GPT 认输了。
期间经历了 FFMPEG 版本的问题,GPU 版本的问题,以及 Docker 中运行FFMPEG 的问题。
总的来说,按 GPT 生成的命令执行以后,遇到报错,发给 GPT 以后可以正确识别到报错的原因,并能给出相应的解决办法。
最后遇到了 FFMPEG 多路信号平滑切换的问题,GPT 给出的命令如下:
要实现流切换过程中的平滑过渡,避免出现断流情况,你可以考虑使用FFmpeg的动态画面转换(Dynamic Picture Resizing)功能。该功能允许在切换流时动态调整输出流的分辨率和比特率,以实现平滑过渡。
以下是一个示例命令,结合了动态画面转换和流切换的功能:
ffmpeg -i rtmp://play.baidu.com/sz-live/20230615-s01 -i rtmp://play.baidu.com/sz-live/20230615-s02 -i rtmp://play.baidu.com/sz-live/20230615-s03 -filter_complex "[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v0]; [1:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v1]; [2:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v2]; [v0][v1][v2]concat=n=3:v=1:a=0[outv]" -map "[outv]" -c:v libx264 -preset veryfast -crf 18 -f flv rtmp://output-url
在上述命令中,我们在每个输入流的处理链中添加了setsar=1过滤器,用于设置输出流的样纵横比(Sample Aspect Ratio)为1:1,以避免在切换流时出现变形。
此外,我们还指定了-c:v libx264 -preset veryfast -crf 18等参数,用于指定输出流的视频编码器和相关设置。你可以根据需要调整这些参数。
请确保替换示例命令中的输入和输出URL,并运行命令。这样修改后的命令应该能够实现流切换过程中的平滑过渡,避免出现断流情况,并且输出流的分辨率为1920×1080。
后来我又想到,如果使用 OBS 实现的话,如何实现,GPT 根据指引,一步步生成了 Python 版本的Script
import obspython as obs
timer_interval = 10 # 切换场景的时间间隔(秒)
scenes = [] # 场景列表
current_scene_index = 0 # 当前场景索引
timer_id = None # 定时器ID
def switch_scene():
global current_scene_index
scene_count = len(scenes)
if scene_count == 0:
return
scene_name = scenes[current_scene_index]
obs.script_log(obs.LOG_INFO, "切换场景:" + scene_name)
if obs.obs_frontend_streaming_active():
obs_frontend_set_current_scene(scene_name)
else:
obs_frontend_set_current_preview_scene(scene_name)
current_scene_index = (current_scene_index + 1) % scene_count
def timer_callback():
switch_scene()
def obs_frontend_set_current_scene(scene_name):
scene = obs.obs_get_source_by_name(scene_name)
obs.obs_frontend_set_current_scene(scene)
obs.obs_source_release(scene)
def obs_frontend_set_current_preview_scene(scene_name):
scene = obs.obs_get_source_by_name(scene_name)
obs.obs_frontend_set_current_preview_scene(scene)
obs.obs_source_release(scene)
def script_description():
return "定时切换场景脚本"
def script_update(settings):
global timer_interval
timer_interval = obs.obs_data_get_int(settings, "timer_interval")
# 停止旧定时器
if timer_id is not None:
obs.timer_remove(timer_id)
timer_id = None
if timer_interval > 0:
# 启动新定时器
timer_id = obs.timer_add(timer_callback, timer_interval * 1000)
def script_load(settings):
global scenes
scene_list = obs.obs_frontend_get_scene_names()
scenes = [scene for scene in scene_list]
obs.source_list_release(scene_list)
def script_properties():
props = obs.obs_properties_create()
# 添加定时参数
obs.obs_properties_add_int(props, "timer_interval", "切换间隔(秒)", 1, 3600, 1)
return props
调教过程中的几个体验
- GPT 对各种最新的文档,索引速度是非常快的,我用的 OBS 29.1版本,GPT可以准确提示哪些 API 是过期的
- GPT的代码还是无法完整运行,需要经过指引,进行针对性的优化
- 有几个地方有问题,我按 GPT 生成的代码中的关键接口,google 到原始出处以后,告诉 GPT 有问题,进行多次修改
- 基本代码有了以后,最终还是在自己的修改和调试下验证通过
- 遇到了两次睁眼说瞎话和上下文混乱
- 整体上没有任何 OBS 的开发经验,可以在 GPT 的引导下找到思路,减少了很多不必要的学习时间。
最后的成果