-1

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.

saurav
  • 131
  • 1
  • 9
  • Could you post the raw ffmpeg log rather than script captured version? It's impossible to read and make sense out of it. – kesh Apr 30 '22 at 14:55
  • @kesh sorry for a delayed response.I don't have the raw ffmpeg output. I am running the ffmpeg commands as a subprocess inside a recording application I am building using nodejs. Is there a way I can capture the raw ffmpeg output from the subprocess? – saurav May 07 '22 at 15:51
  • I think the key is *not* to capture the stderr. So, the ffmpeg stderr goes straight to the console, where you are running the node.js. – kesh May 07 '22 at 15:55
  • Now, you gave me a fresh eyes to reread your question, I may have an idea (and your log may not tell us). How are you terminating the ffmpeg child process in node.js? Most importantly, are you closing the `stdin` then waiting for ffmpeg to complete its task? – kesh May 07 '22 at 16:00
  • No, I am not waiting for FFMPEG to complete it's task! Can that be the issue? I am killing the ffmpeg subprocess 1st and then closing the stdin after that. – saurav May 07 '22 at 16:06
  • 100%. I'm putting together an answer with the explanation – kesh May 07 '22 at 16:20

2 Answers2

0
  • 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"
VC.One
  • 14,790
  • 4
  • 25
  • 57
  • I tried your suggested option. The error is still the same. I have added the ffmpeg options I am currently using for successfully recording in the WebM format. Can you suggest changes needed to capture in the MP4 format? – saurav May 07 '22 at 15:52
  • See if the edit, with added `-f webm`, helps FFmpeg to make a playable video. – VC.One May 07 '22 at 21:42
0

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.

kesh
  • 4,515
  • 2
  • 12
  • 20
  • I tried today by closing the stdin first and then waiting for the process to complete. But still the result is the same. After checking the mp4 file size, I realized that ffmpeg may not have recorded any streams at all! the file size shows 48B and it doesn't contain any streams of video or audio. I doubt that ffmpeg may have dropped all packets without storing anything. This line is very common through out the log. Can this be the cause of any problem? 'cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)\n' – saurav May 09 '22 at 06:37
  • Because you're not filtering, the warning usually points to corrupted input file/stream with inconsistent frame timestamps. That being said, what happens if you drop `-r 25` input option? This framerate may be different from the actual framerate and forcing it could screw up the timestamps. – kesh May 09 '22 at 13:30