如何从 .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 的现有广播配置中?

【问题讨论】:

可以使用带有reloadtextfile 选项的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 将其作为文本放入视频中?的主要内容,如果未能解决你的问题,请参考以下文章

从mp3获取没有元数据(ID3)的数据的方法[关闭]

使用 android.media.Rating 从 android 中的歌曲列表 (MP3) 中获取评分元数据

使用 html5 文件系统 api 获取本地 mp3 文件的元数据

如何从 C# 中的文件中获取元数据? [复制]

powershell Get-MetaData旨在从文件中获取元数据......最初用于查找.mp3的比特率。

使用 NAudio 从 MP3 广播流中获取元数据