使用ffmpeg在webm传输流中生成时间戳 [英] Generating timestamps in webm transport stream with ffmpeg
问题描述
我正在将我的Electron应用程序的屏幕截图记录到文件中,如此处所示:
I am recording screen capture of my Electron app to a file, as suggested here: Save captured video to file in Electron
效果很好,但是文件是传输流".我可以在Chrome浏览器中播放它,但无法调整时间滑块.
It works great, but the file is a "transport stream". I can play it in Chrome browser, but can’t adjust the time slider.
建议使用 ffmpeg
对文件进行后处理.我发现的最简单,直接的命令是:
The suggestion was to use ffmpeg
to post-process the file. The simplest, straight-forward command I found is:
ffmpeg -fflags +genpts -i in.webm out.webm
我认为这只是生成时间戳.但是, out.webm
文件比 in.webm
小15倍!我认为质量没有任何变化.缺点是-处理过程与视频时长大致相同.
I thought that this simply generates timestamps. However, the out.webm
file is 15 times smaller than in.webm
! I don’t see any change in the quality. The downside is - the processing takes about the same time as the duration of the video.
两个问题:
- 有什么办法可以加快这个时间戳"过程吗?
- 我可以录制已经小15倍的视频吗?
我在调用 webkitGetUserMedia()
时指定 maxFrameRate:30
.
以下是该 ffmpeg
命令的输出:
vlad$ ffmpeg -fflags +genpts -i in.webm out.webm
ffmpeg version 4.3.2 Copyright (c) 2000-2021 the FFmpeg developers
built with Apple clang version 12.0.0 (clang-1200.0.32.29)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.2 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, matroska,webm, from 'in.webm':
Metadata:
encoder : Chrome
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv), 2560x1416, SAR 1:1 DAR 320:177, 1k tbr, 1k tbn, 1k tbc (default)
Metadata:
alpha_mode : 1
Stream mapping:
Stream #0:0 -> #0:0 (vp9 (native) -> vp9 (libvpx-vp9))
Press [q] to stop, [?] for help
[libvpx-vp9 @ 0x7f85f2012600] v1.9.0
[libvpx-vp9 @ 0x7f85f2012600] Neither bitrate nor constrained quality specified, using default CRF of 32
Output #0, webm, to 'out.webm':
Metadata:
encoder : Lavf58.45.100
Stream #0:0(eng): Video: vp9 (libvpx-vp9), yuv420p, 2560x1416 [SAR 1:1 DAR 320:177], q=-1--1, 1k fps, 1k tbn, 1k tbc (default)
Metadata:
alpha_mode : 1
encoder : Lavc58.91.100 libvpx-vp9
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
frame= 209 fps=5.8 q=0.0 Lsize= 881kB time=00:00:17.81 bitrate= 405.0kbits/s speed=0.494x
video:879kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.231567%
这是来自 ffprobe
的两个文件的信息:
And here is the information on both files from ffprobe
:
vlad$ ffprobe in.webm
ffprobe version 4.3.2 Copyright (c) 2007-2021 the FFmpeg developers
built with Apple clang version 12.0.0 (clang-1200.0.32.29)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.2 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, matroska,webm, from 'in.webm':
Metadata:
encoder : Chrome
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv), 2560x1416, SAR 1:1 DAR 320:177, 1k tbr, 1k tbn, 1k tbc (default)
Metadata:
alpha_mode : 1
和
vlad$ ffprobe out.webm
ffprobe version 4.3.2 Copyright (c) 2007-2021 the FFmpeg developers
built with Apple clang version 12.0.0 (clang-1200.0.32.29)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.2 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, matroska,webm, from 'out.webm':
Metadata:
ENCODER : Lavf58.45.100
Duration: 00:00:17.82, start: 0.000000, bitrate: 405 kb/s
Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv), 2560x1416, SAR 1:1 DAR 320:177, 1k tbr, 1k tbn, 1k tbc (default)
Metadata:
ALPHA_MODE : 1
ENCODER : Lavc58.91.100 libvpx-vp9
DURATION : 00:00:17.815000000
推荐答案
我非常确定您的FFmpeg处理与您想像的不完全相同-使用命令行,尤其是在缺少某些显式开关的情况下,FFmpeg 会自行决定对视频和音频进行转码,这就是为什么您的输出文件要小得多的原因-数据已重新压缩,可能会导致质量下降.
I am fairly sure your FFmpeg processing isn't exactly what you think it is -- with your command line, particularly with absence of certain explicit switches, FFmpeg will transcode your video and audio at its own discretion, which is why your output file is much smaller -- the data have been re-compressed, with potentially loss of quality.
如果您只想生成大多数玩家所需的索引,和避免不必要的转码,则以下命令行就足够了:
If you just want to generate the index necessary for the kind of seeking most players do, and avoid the undesired transcoding, the following command line will suffice:
ffmpeg -i <input-file> -codec copy <output-file>
有一点需要注意的是,请注意,如果没有其他明确的开关来指示它,否则FFmpeg会从输出文件扩展名中推断出输出容器格式.我假设您的输入和输出都是WebM,所以您的情况没有任何问题.但是,即使不是这样,将媒体重新混合到另一种格式的容器中也不一定会导致质量损失.
On a minor note, do take into account that without an additional explicit switch to instruct it otherwise, FFmpeg infers the output container format from the output file name extension. I assume both your input and output are WebM, so there isn't any issue in your case. But even if they weren't, re-muxing media into another format of container doesn't have to result in quality loss.
正如您从上面的命令行中推测的那样,仅运行FFmpeg而没有任何与帧时间索引的生成"有关的显式开关,无论如何都会使FFmpeg建立索引.无论是否进行转码,它都会这样做.
As you can surmise from the command line above, just running FFmpeg without any explicit switch pertaining to "generation of frame time index", causes it to build the index anyway. It will do so with or without transcoding taking place.
P.S.有一些参与者,例如[现在废弃的] MPC-HC ,它们至少可以寻找一些参与者.运输流.我知道事实上它可以寻找您的WebM媒体.我不知道它实际如何执行搜索的确切细节,但是如果我想我想说的是,它只是从媒体中某个适当的位置(或最开始的位置)进行线性搜索,以找到与时间匹配的帧寻找.就像在数据库表中查找没有索引以帮助搜索谓词的行.
P.S. There are some players, like [the now abandoned] MPC-HC, which are able to seek at least some transport streams. I know for a fact it can seek your kind of WebM media. I don't know the exact details on how it actually does the seeking, but if I would guess I'd say it simply does a linear search from some appropriate location in the media (or the very beginning) for a frame matching the time of seek. Much like looking for a row in a database table which doesn't have an index to help with the search predicate.
这篇关于使用ffmpeg在webm传输流中生成时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!