问题
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