使用ffmpeg在webm传输流中生成时间戳 [英] Generating timestamps in webm transport stream with ffmpeg

查看:140
本文介绍了使用ffmpeg在webm传输流中生成时间戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将我的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.

两个问题:

  1. 有什么办法可以加快这个时间戳"过程吗?
  2. 我可以录制已经小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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆