如何从 .mp3 文件中获取元数据并使用 FFmpeg 将其作为文本放入视频中?
Posted
技术标签:
【中文标题】如何从 .mp3 文件中获取元数据并使用 FFmpeg 将其作为文本放入视频中?【英文标题】:How to take metadata from .mp3 file and put it to a video as a text using FFmpeg? 【发布时间】:2021-03-17 13:22:54 【问题描述】:在我之前打开的主题中:
How to make FFmpeg automatically inject mp3 audio tracks in the single cycled muted video
我从@llogan 那里得到了详细的解释,如何在 youtube 上播放循环的短静音视频,在不中断翻译的情况下自动在其中注入音轨。
我计划增强流程,我面临的下一个问题是如何动态地将附加文本添加到广播中。
先决条件:
-
youtube 广播由 ffmpeg 启动并运行
3 分钟短视频无限循环播放
播放列表中的音轨由“ffmpeg concat”自动获取并一一注入视频中
这是开始翻译的基本命令:
ffmpeg -re -fflags +genpts -stream_loop -1 -i video.mp4 -re -f concat -i input.txt -map 0:v -map 1:a -c:v libx264 -tune stillimage -vf format=yuv420p -c:a copy -g 20 -b:v 2000k -maxrate 2000k -bufsize 8000k -f flv rtmp://a.rtmp.youtube.com/live2/my-key
我想带来的改进
-
我打算在音频文件中存储一些元数据(基本上是艺术家名和歌曲名)
在一首特定歌曲开始播放时,艺术家/歌曲名称应从元数据中获取,并在整首歌曲播放期间作为文本显示在视频上。
当当前歌曲结束并且新歌曲开始播放时,应将之前的艺术家/歌曲文本替换为新歌曲等
我的问题是如何正确获取元数据并将其添加到使用 ffmpeg 的现有广播配置中?
【问题讨论】:
可以使用带有reload
和textfile
选项的drawtext 过滤器(请参阅Can you insert text from a file in real time with ffmpeg streaming?)。问题是input.txt
中列出的音频文件基本上都被当作单一输入,失去了“个性”。所以问题变成了时间问题:你怎么知道什么时候更新标题?
因此,如果没有办法使用音频文件的元数据作为文本的输入,这将成为一项非常复杂的任务。我可以假设的是,如果我们在 input.txt
中有名为 file1.m4a, file2.m4a 的文件,那么我们需要有与 file1.txt 等文件名对应的单独文本文件, file2.txt 包含文本并从中取出文本。然后可能每次新歌曲开始时,我们应该确定其文件名持续时间或保留一个单独的文件(-s),其中包含有关所有曲目持续时间的信息。但这似乎不是一个简单的解决方案
基本上这个 youtube 频道是我想要实现的 lil-peep radio 我意识到他们可以使用完全不同的方法,例如使用 OBS 的流、Streamlabs 覆盖、一些音频播放器作为音频输入。但我认为 ffmpeg 是一种更轻量级且硬件消耗更少的解决方案
【参考方案1】:
这是一个相当广泛的问题,我没有完整的解决方案。但我可以提供包含几个命令的部分答案,您可以使用这些命令来帮助实施解决方案。
更新视频点播文字
见Can you insert text from a file in real time with ffmpeg streaming?
获取标题和艺术家元数据
ffprobe
:
ffprobe -v error -show_entries format_tags=title -of default=nw=1:nk=1 input.mp3
ffprobe -v error -show_entries format_tags=artist -of default=nw=1:nk=1 input.mp3
或组合:format_tags=title,artist
(请注意,title
将首先显示,然后是 artist
,无论命令中的顺序如何)。
获取歌曲的时长
见How to get video duration in seconds?
你需要弄清楚什么
困难的部分是知道何时在drawtext过滤器中更新textfile
中引用的文件,如上面Update text on video on demand所示。
懒惰的解决方案
预先制作每首歌曲的视频,包括标题和艺术家信息。简单的 Bash 示例:
audio=input.mp3; ffmpeg -stream_loop -1 -i video.mp4 -i "$audio" -filter_complex "[0:v]scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720,setsar=1,fps=25,drawtext=text='$(ffprobe -v error -show_entries format_tags=title,artist -of default=nw=1:nk=1 $audio)':fontsize=18:fontcolor=white:x=10:y=h-th-10,format=yuv420p[v]" -map "[v]" -map 1:a -c:v libx264 -c:a aac -ac 2 -ar 44100 -g 50 -b:v 2000k -maxrate 2000k -bufsize 6000k -shortest "$audio%.*.mp4"
既然您已经进行了编码,并且所有内容都符合相同的属性以进行正确的连接,您可能只需 stream copy 您的播放列表到 YouTube(但我没有测试):
ffmpeg -re -f concat -i input.txt -c copy -f flv rtmp://a.rtmp.youtube.com/live2/my-key
关于如何dynamically update the playlist,请参阅您之前的问题。
参考资料:
FFmpeg Wiki: Streaming to YouTube Resizing videos with ffmpeg to fit into specific size How to concatenate videos in ffmpeg with different attributes?【讨论】:
以上是关于如何从 .mp3 文件中获取元数据并使用 FFmpeg 将其作为文本放入视频中?的主要内容,如果未能解决你的问题,请参考以下文章
使用 android.media.Rating 从 android 中的歌曲列表 (MP3) 中获取评分元数据
使用 html5 文件系统 api 获取本地 mp3 文件的元数据