shell 黑屏时的回退输入ffmpeg

ryoqjall  于 2022-11-25  发布在  Shell
关注(0)|答案(1)|浏览(130)

bounty将在4天后过期。回答此问题可获得+500的声望奖励。Mint希望吸引更多人关注此问题:有一个类似的问题,很想听到一些选择。我只是想要一个回退饲料,是它回来,图像,视频,只是一些ffmpeg自动福尔斯退时,原来的来源是不可用的,所以flv流到YouTube是不间断的。

我希望在使用ffmpeg命令时有一个“回退”视频。目标是我播放一个视频,一旦这个视频显示几乎黑屏,应该有一个回退开关,并在黑屏结束时重新切换。我知道我们可以检测到“黑框”,但我迷路了。。如果有人有什么想法?
我现在就在这里(我使用streamlink来获取输入):

streamlink <<THE_URL>> best -O | ffmpeg -re -i pipe:0 -c:v libx264 -vf "blackframe=amount=40:thresh=5" -c:a aac -strict -2 -f flv <<RTMP_URL>> | grep blackframe

谢谢你

ac1kyiln

ac1kyiln1#

我们可以使用geq、alphamerge和覆盖过滤器来解决该问题:
streamlink <<THE_URL>> best -O | ffmpeg -i pipe: -f lavfi -i smptebars=size=384x216:rate=30 -filter_complex "[1:v][0:v]scale2ref[v1][v0];[v0]format=gray,geq=lum_expr='lt(p(X,Y), 5)',geq='gt(lumsum(W-1,H-1),0.4*W*H)*255'[alpha];[v1][alpha]alphamerge[alpha_v1];[0:v][alpha_v1]overlay=shortest=1[v]" -map "[v]" -map 0:a -c:v libx264 -pix_fmt yuv420p -c:a aac -strict -2 -f flv <<RTMP_URL>>
上述示例使用smptebars合成图案作为后备视频。
scale 2 ref用于将图案的分辨率调整为主输入视频的分辨率。
为获得最佳效果,rate参数(如rate=30)应与主视频的帧速率匹配。
我们可以选择用视频文件的后备替换合成模式-后备视频应该足够长(或者使用stream_loop参数循环播放),并且帧率更好地匹配主输入。
注意事项:

  • 使用blackframe是行不通的,因为检测到的黑帧的列表被打印出来,并且不能用于修改“飞行中”的主视频(该列表可以在离线处理的第二遍中使用)。

筛选器链说明:

  • [1:v][0:v]scale2ref[v1][v0]-将备用视频缩放到主输入视频的分辨率。
  • [v0]format=gray,geq=lum_expr='lt(p(X,Y), 5)[alpha]'-将所有低于阈值5的像素替换为值1,并将高于5的像素设置为0
  • geq='gt(lumsum(W-1,H-1),0.4*W*H)*255'-如果1像素之和超过总像素的40%,则将相关帧中的所有像素设置为2550.4*W*H适用于总像素的40%)。

如果总像素的40%低于5,则[alpha]为黑色(全零)。
如果总像素的40%或更多高于5,则[alpha]为白色(所有255)。

  • [v1][alpha]alphamerge[alpha_v1]-将[alpha]作为Alpha通道合并到缩放的回退帧[v1]

如果[alpha]是黑色,则[alpha_v1]是完全透明的。
如果[alpha]是白色,则[alpha_v1]是完全不透明的。

  • [0:v][alpha_v1]overlay=shortest=1[v]-将[alpha_v1]覆盖在主视频帧上。

如果[alpha_v1]是透明的,则不会修改主视频帧。
如果[alpha_v1]是不透明的,主视频帧将替换为备用帧。

测试:

使用沿着时间变暗的帧创建合成视频:
ffmpeg -y -f lavfi -i testsrc=size=192x108:rate=1:duration=10 -filter_complex "[0:v]format=rgb24[v0];[v0][0:v]blend=all_mode='overlay':all_expr='max(A*0.5-T*15\,0)',format=rgb24[v]" -map "[v]" -vcodec libx264 -pix_fmt yuv420p in.mp4
视频为10帧,最后两帧被认为是“黑帧”。
一个一个......
第一次
执行blackframe过滤器(用作参考):
ffmpeg -y -hide_banner -loglevel info -i in.mp4 -vf "format=gray,blackframe=amount=40:thresh=5" -c:v libx264 -pix_fmt yuv420p out.flv
最后两帧标记为“黑帧”:
[解析的黑色帧_1@00000285e905fc40]帧:8 p黑色:52点:131072 t:8.000000类型:P最后关键帧:0
[解析的黑色帧_1@00000285e905fc40]帧:9 p黑色:100点:147456 t:9.000000类型:P最后关键帧:0
将低于5的像素标记为白色像素(测试format=gray,geq=lum_expr='lt(p(X,Y), 5)):
x1米35英寸
前两帧具有少量暗像素,后两帧具有大量暗像素(最后一个图像是白色):
一个四个一个一个五个一个...
第一次
测试geq='gt(lumsum(W-1,H-1),0.4*W*H)
x1米37英寸
前8帧为黑色,后2帧为白色:
一个八个一个一个一个
第10页
测试整个过滤器链:
x1米38英寸
最后两帧将替换为备用视频:
第一次
第14天
注意事项:

  • 上述解决方案可能不能实时工作,因为滤波器链可能计算强度太大。

为了减少计算时间,我们可以缩小输入视频,在缩小的帧上应用产生alpha的阶段,并在alphamerge之前放大alpha。
twitch.tv测试实时流(通过管道连接到FFplay):
streamlink https://www.twitch.tv/ninja --default-stream 480p -O | ffmpeg -i pipe: -f lavfi -i smptebars=size=384x216:rate=30 -filter_complex "[1:v][0:v]scale2ref[v1][v0];[v0]format=gray,geq=lum_expr='lt(p(X,Y), 5)',geq='gt(lumsum(W-1,H-1),0.4*W*H)*255'[alpha];[v1][alpha]alphamerge[alpha_v1];[0:v][alpha_v1]overlay=shortest=1[v]" -map "[v]" -map 0:a -c:v libx264 -pix_fmt yuv420p -c:a aac -strict -2 -f flv pipe: | ffplay pipe:
在五月的机器,480 p质量是工作,但与720 p60的CPU利用率在100%,和视频口吃。

相关问题