FFmpeg pipe input, error while transcoding from WebM to MP4

1.4k views Asked by At

I am trying to record a video from pipe input using FFMPEG. The pipe input is in WebM format i.e. the video codec is VP8 and the audio codec is OPUS. I am able to save the output video in the WebM format using FFMPEG without any issue. But when I am trying to save it in MP4 format, I am not getting the desired output. Though there are no errors while saving, the output file shows an error with description " This file contains no playable streams!."

These are the options for successfully recording in the WebM format.

    '-loglevel', 'debug', '-protocol_whitelist', 'pipe,udp,rtp', 
'-fflags', '+genpts', '-i', 'pipe:0', '-map', '0:v:0', '-c:v', 
'copy', '-map', '0:a:0', '-strict', '-2', '-c:a', 'copy', '-flags',
 '+global_header', '-f', 'webm', 'output.webm'

Here are my ffmpeg options for recording in the MP4 format.

    '-thread_queue_size', '4096', '-r', '25', '-i', 'pipe:0', 
    '-c:v', 'libx264', '-preset', 'veryFast', '-pix_fmt', 'yuvj420p', 
    '-acodec', 'aac', "output.mp4"

Console output after executing this command as a subprocess

> ffmpeg::process::data [data:'  libavutil      56. 31.100 / 56. 
31.100\n' + '  libavcodec     58. 54.100 / 58. 54.100\n' + '  
libavformat    58. 29.100 / 58. 29.100\n' + '  libavdevice    58. 
 8.100 / 58.  8.100\n' + '  libavfilter     7. 57.100 /  7. 57.100\n'
 + '  libavresample   4.  0.  0 /  4.  0.  0\n' + '  libswscale 
     5.  5.100 /  5.  5.100\n' + '  libswresample   3.  5.100 /  3.
  5.100\n' + '  libpostproc    55.  5.100 / 55.  5.100\n'] +1ms
> 
> ffmpeg ffmpeg::process::data [data:"Input #0, matroska,webm, from
> 'pipe:0':\n" + '  Metadata:\n' + '    encoder         : Chrome\n' + ' 
> Duration: N/A, start: 0.000000, bitrate: N/A\n' + '    Stream
> #0:0(eng): Audio: opus, 48000 Hz, stereo, fltp (default)\n' + ' 
   Stream #0:1(eng): Video: vp8, yuv420p(progressive), 1920x950, SAR 1:1
> DAR 192:95, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)\n' + '   
> Metadata:\n' + '      alpha_mode      : 1\n'] +1s
> 
> 
>  ffmpeg::process::data [data:'Stream mapping:\n' + '  Stream #0:1 ->
> #0:0 (vp8 (native) -> h264 (libx264))\n' + '  Stream #0:0 -> #0:1 
(opus (native) -> aac (native))\n'] +1ms
> 
>    ffmpeg::process::data [data:'[swscaler @ 0x55a63050ddc0] deprecated
> pixel format used, make sure you did set range correctly\n'] +23ms
> 
>   ffmpeg::process::data [data:'[libx264 @ 0x55a630489980] using
> SAR=1/1\n'] +10ms
> 
>   ffmpeg::process::data [data:'[libx264 @ 0x55a630489980] using cpu
> capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2\n'] +0ms
> 
>   ffmpeg::process::data [data:'[libx264 @ 0x55a630489980] profile
> High, level 4.0\n'] +8ms
> 
>   ffmpeg::process::data [data:'[libx264 @ 0x55a630489980] 264 - core
> 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 -
> http://www.videolan.org/x264.html - options: cabac=1 ref=1
> deblock=1:0:0 analyse=0x3:0x113 me=hex subme=2 psy=1 psy_rd=1.00:0.00
> mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0
> deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=18
> lookahead_threads=6 sliced_threads=0 nr=0 decimate=1 interlaced=0
> bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1
> b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=250
> keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=crf
> mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40
> aq=1:1.00\n'] +1ms
> 
>   ffmpeg::process::data [data:"Output #0, mp4, to 'output.mp4':\n" + '
> Metadata:\n' + '    encoder         : Lavf58.29.100\n' + '    Stream
> #0:0(eng): Video: h264 (libx264) (avc1 / 0x31637661), 
yuvj420p(pc), 1920x950 [SAR 1:1 DAR 192:95], q=-1--1, 25 fps, 12800 tbn, 25 tbc
> (default)\n' + '    Metadata:\n' + '      alpha_mode      : 1\n' + '  
> encoder         : Lavc58.54.100 libx264\n' + '    Side data:\n' + '   
> cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1\n' + '   
> Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz,
> stereo, fltp, 128 kb/s (default)\n' + '    Metadata:\n' + '     
> encoder         : Lavc58.54.100 aac\n'] +0ms
> 
> ffmpeg::process::data [data:'frame=   45 fps=0.0 q=28.0 size=      
> 0kB time=00:00:01.87 bitrate=   0.2kbits/s speed=3.48x    \r'] +505ms
> 
> ffmpeg::process::data [data:'frame=   61 fps= 56 q=28.0 size=      
> 0kB time=00:00:02.41 bitrate=   0.2kbits/s speed=2.22x    \r'] +564ms
> 
> ffmpeg::process::data [data:'frame=   76 fps= 48 q=28.0 size=      
> 0kB time=00:00:02.88 bitrate=   0.1kbits/s speed=1.81x    \r'] +492ms

I have a doubt on this output as it may have been causing the issue.

ffmpeg::process::data [data:'[swscaler @ 0x55a63050ddc0] deprecated
 pixel format used, make sure you did set range correctly\n'] +23ms

I hope I have provided enough information about the issue I am facing. Please ask for any other information needed to understand the issue correctly.

I am sure that I am missing some ffmpeg options which is causing this issue. But I am not able to identify them! Any help in correcting this issue would be greatly appreciated.

Thank you.

2

There are 2 answers

2
VC.One On
  • Most H.264 decoders usually expect YUV420p pixel format.
  • You do not tell FFmpeg the input format of media data from the pipe.

Try as:

'-thread_queue_size', '4096', '-f', 'webm', '-r', '25', '-i', 'pipe:0', 
'-c:v', 'libx264', '-preset', 'veryFast', '-pix_fmt', 'yuv420p', 
'-acodec', 'aac', '-movflags', '+faststart', "output.mp4"
2
kesh On

If you are piping data to ffmpeg process, always close the stdin first then wait for the ffmpeg process to complete on its own. This is absolutely critical especially for the MP4 format, but it is a good practice in general.

The one of the primary differences between MP4 and MKV is that MP4 stores its stream info (aka MOOV packet) at the end of the file by default. So, if you kill the ffmpeg prematurely (e.g., right after writing the last frame to the pipe) you are not giving ffmpeg a chance to write the MOOV packet, which results in unusable file.