How can I mux a MKV and MKA file and get it to play in a browser?

只谈情不闲聊 提交于 2019-12-25 09:34:44

问题


I'm using ffmpeg to merge .mkv and .mka files into .mp4 files. My current command looks like this:

ffmpeg -i video.mkv -i audio.mka output_path.mp4

The audio and video files are pre-signed urls from Amazon S3. Even on a server with sufficient resources, this process is going very slowly. I've researched situations where you can tell ffmpeg to skip re-encoding each frame, but I think that in my situation it actually does need to re-encode each frame.

I've downloaded 2 sample files to my macbook pro and have installed ffmpeg locally via homebrew. When I run the command

ffmpeg -i video.mkv -i audio.mka -c copy output.mp4

I get the following output:

ffmpeg version 3.3.2 Copyright (c) 2000-2017 the FFmpeg developers
  built with Apple LLVM version 8.1.0 (clang-802.0.42)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.3.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libmp3lame --enable-libx264 --enable-libxvid --enable-opencl --disable-lzma --enable-vda
  libavutil      55. 58.100 / 55. 58.100
  libavcodec     57. 89.100 / 57. 89.100
  libavformat    57. 71.100 / 57. 71.100
  libavdevice    57.  6.100 / 57.  6.100
  libavfilter     6. 82.100 /  6. 82.100
  libavresample   3.  5.  0 /  3.  5.  0
  libswscale      4.  6.100 /  4.  6.100
  libswresample   2.  7.100 /  2.  7.100
  libpostproc    54.  5.100 / 54.  5.100
Input #0, matroska,webm, from '319_audio_1498590673766.mka':
  Metadata:
    encoder         : GStreamer matroskamux version 1.8.1.1
    creation_time   : 2017-06-27T19:10:58.000000Z
  Duration: 00:00:03.53, start: 2.831000, bitrate: 50 kb/s
    Stream #0:0(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
    Metadata:
      title           : Audio
Input #1, matroska,webm, from '319_video_1498590673766.mkv':
  Metadata:
    encoder         : GStreamer matroskamux version 1.8.1.1
    creation_time   : 2017-06-27T19:10:58.000000Z
  Duration: 00:00:03.97, start: 2.851000, bitrate: 224 kb/s
    Stream #1:0(eng): Video: vp8, yuv420p(progressive), 640x480, SAR 1:1 DAR 4:3, 30 tbr, 1k tbn, 1k tbc (default)
    Metadata:
      title           : Video
[mp4 @ 0x7fa4f0806800] Could not find tag for codec vp8 in stream #0, codec not currently supported in container
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Stream mapping:
  Stream #1:0 -> #0:0 (copy)
  Stream #0:0 -> #0:1 (copy)
    Last message repeated 1 times

So it appears that the specific encodings I'm working with are vp8 videos and opus audio files, which I believe are incompatible with the .mp4 output container. I would appreciate answers that cover ways of optimally merging vp8 and opus into .mp4 output or answers that point me in the direction of output media formats that are both compatible with vp8 & opus and are playable on web and mobile devices so that I can bypass the re-encoding step altogether.

EDIT:

Just wanted to provide a benchmark after following LordNeckbeard's advice:

4 min 41 second video transcoded locally on my mac

LordNeckbeard’s approach : 15 mins 55 seconds (955 seconds)
Current approach : 18 mins 49 seconds (1129 seconds)

18% speed increase

回答1:


You can use ffmpeg to mux and/or re-encode MKV and MKA into web browser compatible formats such as Webm or MP4.

Webm mux: If the input formats are VP8/VP9 video with Vorbis or Opus audio

You can just mux into Webm if your inputs are VP8 or VP9 video and Vorbis or Opus audio, such as the inputs in your question. This should be fast because it will not re-encode:

ffmpeg -i video.mkv -i audio.mka -c copy output.webm

Default stream selection behavior is to select one stream per stream type, so with -map you can tell it which streams to choose to prevent mistakes. For example, if both inputs contain multiple streams, but you only want to first video stream from video.mkv and the first audio stream from audio.mka:

ffmpeg -i video.mkv -i audio.mka -map 0:v:0 -map 1:a:0 -c copy -movflags +faststart output.webm

MP4 mux: If the input formats are H.264/H.265 video and AAC audio

ffmpeg -i video.mkv -i audio.mka -c copy -movflags +faststart output.mp4
  • -movflags +faststart was added because you mentioned web playback. This will allow the video to begin playback before it is completely downloaded by the client.

Webm Re-encode: If the input formats are not compatible with Webm

You'll need to re-encode:

ffmpeg -i video.mkv -i audio.mka -c:v libvpx-vp9 -crf 33 -b:v 0 -c:a libopus output.webm
  • VP9 is really slow. If you want VP8 instead use -c:v libvpx. For more info see FFmpeg Wiki: VP8 and FFmpeg Wiki: VP9.

  • If you don't have libopus support use libvorbis instead.

MP4 Re-encode: If the input formats are not compatible with MP4

ffmpeg -i video.mkv -i audio.mka -c:v libx264 -crf 23 -preset medium -c:a aac -movflags +faststart output.mp4
  • For video, control quality with -crf and encoding speed with -preset. See FFmpeg Wiki: H.264 and FFmpeg Wiki: AAC for more info.

  • If your target devices are limited in the H.264 profiles they support you can add -profile:v main or -profile:v baseline.

ffprobe for scripting

You can make a script to automate this. ffprobe can be used to determine the formats:

$ ffprobe -loglevel error -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 video.mkv
h264
$ ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of csv=p=0 audio.mka 
aac

The ffprobe outputs can be used as variables in an if/then statement.



来源:https://stackoverflow.com/questions/44785730/how-can-i-mux-a-mkv-and-mka-file-and-get-it-to-play-in-a-browser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!