IMHO, MP4 (ISO/IEC 14496-12) is quite complicated. This question is meant for those familiar with ins and outs of MP4, so I try to be brief. Otherwise, this question could be a long essay.
I am trying to create fMP4 with C# (the language is not relevant here). The created fMP4 file does not play. Using the tool ffprobe to check the file generates the following:
ffprobe "foo.mp4"
[h264 # 0000021625d10e40] no frame!
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'foo.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: avc1mp42isomiso6
creation_time : 2022-09-11T00:24:35.000000Z
Duration: 00:00:10.06, start: 0.000000, bitrate: 2078 kb/s
Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x800 [SAR 1:1 DAR 8:5], 2077 kb/s, 12.22 fps, 30 tbr, 1000k tbn, 2000k tbc (default)
Metadata:
creation_time : 2022-09-11T00:24:35.000000Z
handler_name : Media Handler
vendor_id : [0][0][0][0]
encoder : AVC Coding
Please note the error:
[h264 # 0000021625d10e40] no frame!
When I use:
ffprobe -show_frames "foo.mp4"
It shows hundreds of frames of this small MP4 file that seem flawless. I cannot paste them here there are thousands of lines. However, ffprobe shows two errors at the start:
[h264 # 000001b015110ec0] no frame!
[h264 # 000001b01545e7c0] no frame!
Please note these two "no frame!" errors generated by ffprobe -show_frames are different from the first one by ffprobe without the -show_frames option.
I wonder if anyone could offer a tip about what these "no frame!" errors mean and where I should chase the culprit.
The following is what Mp4 Explorer shows:
Update 2022-09-17
Here is an fMP4 file: example.mp4. Every video player seems to be able to play it except for VLC Player. VLC Player is an important player. I would love to make it work for it. Could anyone offer a clue about why VLC Player does not like it?
Related
I am trying to capture the canvas on browser (canvas.captureStream), add audio ( captured using getUserMedia and added to stream using canvasStream.addTracks) and send it to server. Server sends the stream ( after encoding with H264 ) to facebook live using ffmpeg. However the stream is not stable and gets disconnected within minutes.
If the video along with audio tracks (using getMediaUser) is directly(without canvas.captureStream) sent it works fine. I am suspecting it has to do with the audio track not being proper and hence facebook rejecting it ( no particular error from ffmpeg, it just exits with IO error). Need help in figuring out the right way to send canvas stream along with audio.
Current ffmpeg command is as below
ffmpeg -i - -c:v libx264 -crf 23 -preset ultrafast \
-tune zerolatency -max_muxing_queue_size 1000 \
-vsync cfr -async 1 -bufsize 2M -r 30 -g 60 -keyint_min 30 \
-x264opts keyint=30 -pix_fmt yuv420p -level 3 \
-c:a aac -b:a 96k -ar 96000 \
-f tee -map 0:v -map 0:a [f=flv] <rtmp url 1> | [f=flv] <rtmp url 2>
Note: In the above command <rtmp url 1> and <rtmp url 2> are replaced with actual urls ( including the session key required )
My settings to capture canvas and audio on browser are as below
canvasStream = canvas.captureStream(30);
audioTrack = stream.getTracks().filter( (track) => {
return track.kind === 'audio';
})[0];
canvasStream.addTrack(audioTrack);
Note: Audio constraints given in getUserMedia are as below
audio: {
sampleRate: 44100,
echoCancellation: true
}
Error given by ffmpeg while exiting is as below
FFMPEG:[flv # 0x5626ecf0f7c0] Failed to update header with correct duration.
[flv # 0x5626ecf0f7c0] Failed to update header with correct filesize.
FFMPEG:[tee # 0x5626ec8550c0] Slave muxer #1 failed, aborting.
av_interleaved_write_frame(): Broken pipe
FFMPEG:[flv # 0x5626ecbe8840] Failed to update header with correct duration.
FFMPEG:[flv # 0x5626ecbe8840] Failed to update header with correct filesize.
FFMPEG:frame= 2378 fps= 22 q=22.0 Lsize=N/A time=00:01:21.17 bitrate=N/A dup=2202 drop=5 speed=0.745x
video:18916kB audio:959kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
FFMPEG:[libx264 # 0x5626ec855b80] frame I:80 Avg QP:13.97 size:115968
[libx264 # 0x5626ec855b80] frame P:2298 Avg QP:16.77 size: 4392
[libx264 # 0x5626ec855b80] mb I I16..4: 100.0% 0.0% 0.0%
FFMPEG:[libx264 # 0x5626ec855b80] mb P I16..4: 3.8% 0.0% 0.0% P16..4: 9.5% 0.0% 0.0% 0.0% 0.0% skip:86.7%
[libx264 # 0x5626ec855b80] coded y,uvDC,uvAC intra: 26.3% 42.2% 13.6% inter: 2.9% 6.1% 0.1%
[libx264 # 0x5626ec855b80] i16 v,h,dc,p: 34% 26% 23% 17%
[libx264 # 0x5626ec855b80] i8c dc,h,v,p: 46% 27% 20% 7%
[libx264 # 0x5626ec855b80] kb/s:1954.96
[aac # 0x5626ec84d200] Qavg: 122.161
Conversion failed!
Appreciate any help with this.
I am suspecting it has to do with the audio track not being proper and hence facebook rejecting it
Yes, this is correct. Facebook requires an audio track and will drop your stream if it isn't present.
For starters, drop -ar 96000 from your FFmpeg command. This would be setting a sample rate of 96 kHz, which Facebook isn't going to want. You really don't want to resample at FFmpeg anyway... just let it use whatever sample rate it gets from the browser.
Next, set your audio sample rate to 48 kHz rather than 44.1 kHz on your getUserMedia constraints. Facebook doesn't handle 44.1 kHz audio on the RTMP ingest well. (Generally these days, you want to use 48 kHz for everything unless you're targeting CD audio, which would be 44.1 kHz.)
Next, your FFmpeg audio command is outputting to two RTMP URLs. If one fails, they will both fail. If one gets behind, they will both be stalled. This is probably not what you want. :-) Drop one of them.
Now, make sure you have a decent and consistent frame rate. Facebook is very picky about this and will drop your stream.
To test/debug, replace your RTMP URL output with a simple FLV file on disk, to ensure things are working from the browser up through FFmpeg. Once you have that all smooth and working, you can reconnect to Facebook and go from there.
I am batch converting lots of songs into shorter "Advert" songs for SHOUTcast and to be recognised as adverts by the server. The song must have ":Advert" for both the title and the artist metadata tags. When I use the following command:
ffmpeg -i "$i" -c copy -vn -map_metadata -1 -metadata title=":Advert" -metadata artist=":Advert" -t 120 "adverts/ADVERT_$i"
I would expect it to output the song with only ":Advert" as title and artist metadata but when I import it into the radio playout software (using ID3 1.x tagging) the metadata has not copied across and is therefore lost. Output from ffmpeg:
ffmpeg version 3.0.2 Copyright (c) 2000-2016 the FFmpeg developers
built with Apple LLVM version 9.0.0 (clang-900.0.37)
configuration: --prefix=/usr/local/Cellar/ffmpeg/3.0.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libxvid --disable-lzma --enable-vda
libavutil 55. 17.103 / 55. 17.103
libavcodec 57. 24.102 / 57. 24.102
libavformat 57. 25.100 / 57. 25.100
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 31.100 / 6. 31.100
libavresample 3. 0. 0 / 3. 0. 0
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100
[mp3 # 0x7feba6800000] Skipping 0 bytes of junk at 230934.
[mjpeg # 0x7feba7000600] Changing bps to 8
Input #0, mp3, from 'Joakim Karud - Vibe With Me.mp3':
Metadata:
major_brand : dash
minor_version : 0
compatible_brands: iso6mp41
encoder : Lavf56.40.101
artist : Joakim Karud
title : Vibe With Me
Duration: 00:02:53.06, start: 0.025056, bitrate: 138 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 128 kb/s
Metadata:
encoder : Lavc56.60
Stream #0:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 1280x720 [SAR 1:1 DAR 16:9], 90k tbr, 90k tbn, 90k tbc
Metadata:
comment : Cover (front)
Output #0, mp3, to 'adverts/ADVERT_Joakim Karud - Vibe With Me.mp3':
Metadata:
TIT2 : :Advert
TPE1 : :Advert
TSSE : Lavf57.25.100
Stream #0:0: Audio: mp3, 44100 Hz, stereo, 128 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
size= 1876kB time=00:02:00.00 bitrate= 128.1kbits/s speed=1.44e+03x
video:0kB audio:1876kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.024837%
I believe this is happening because the tag names are different (e.g. title should be title, but is TIT2 when output. Please could someone specify how I could ensure that the metadata is encoded in the ID3 1.x format so that it is readable by the radio playout software. Many thanks.
FFmpeg, by default, writes only ID3v2.4 tags. ID3v1 has to be specified for writing.
Use
ffmpeg -i "$i" -c copy -vn -write_id3v1 true -map_metadata -1 -metadata title=":Advert" -metadata artist=":Advert" -t 120 "adverts/ADVERT_$i"
For an app I'm developing, I need avconv to stream from a link for a specified length of time. I've tried using -timelimit to no avail. What am I doing wrong? Is there a better way to do this? Why doesn't -timelimit work?
See, for example, the call below, which runs until terminated with ctrl-c.
stack#ThinkPad:~/app_dev$ avconv -timelimit 30 -i http://br-mp3-bayern2sued-m.akacast.akamaistream.net/7/731/256282/v1/gnl.akacast.akamaistream.net/br_mp3_bayern2sued_m stack_test.mp3
Which generates the following output.
avconv version 9.18-6:9.18-0ubuntu0.14.04.1, Copyright (c) 2000-2014 the Libav developers
built on Mar 16 2015 13:19:10 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
[mp3 # 0x765100] Header missing
[mp3 # 0x75f020] max_analyze_duration reached
[mp3 # 0x75f020] Estimating duration from bitrate, this may be inaccurate
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, mp3, from 'http://br-mp3-bayern2sued-m.akacast.akamaistream.net/7/731/256282/v1/gnl.akacast.akamaistream.net/br_mp3_bayern2sued_m':
Duration: N/A, start: 0.000000, bitrate: 128 kb/s
Stream #0.0: Audio: mp3, 44100 Hz, stereo, s16p, 128 kb/s
Output #0, mp3, to 'stack_test.mp3':
Metadata:
TSSE : Lavf54.20.4
Stream #0.0: Audio: libmp3lame, 44100 Hz, stereo, s16p
Stream mapping:
Stream #0:0 -> #0:0 (mp3 -> libmp3lame)
Press ctrl-c to stop encoding
[mp3 # 0x765100] Header missing
Error while decoding stream #0:0
[mp3 # 0x7639e0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: -2255 >= -2255
-t and -timelimit are different. More importantly, you need to use -t as an output option, not as an input option. Updating your example, the following should work (tested on ffmpeg).
ffmpeg -i http://br-mp3-bayern2sued-m.akacast.akamaistream.net/7/731/256282/v1/gnl.akacast.akamaistream.net/br_mp3_bayern2sued_m -t 30 stack_test.mp3
My problem:
I captured some flv videos with rtmpdump, an example command is this:
rtmpdump -v -r rtmp://aljazeeraflashlivefs.fplive.net/aljazeeraflashlive-live/aljazeera_ara_high -p http://www.elahmad.com/tv/Webtv/Arabian.htm -B 15 -o foo.flv
I realized that not only this command's capture, but all the captures with rtmpdump fails to show the duration when I play the video on a website with flowplayer. This eventually results on failing of streaming, I can not change the playing time.
I did:
I tried to open it with Movie Player in Linux and the duration is seen in there.
I also put the video with flvtool2, it failed:
flvtool2 -U foo.flv
ERROR: undefined local variable or method 'level' for #
ERROR: /usr/lib/ruby/1.8/flv/amf_string_buffer.rb:102:in read__AMF_object'
ERROR: /usr/lib/ruby/1.8/flv/amf_string_buffer.rb:132:ineval'
ERROR: /usr/lib/ruby/1.8/flv/amf_string_buffer.rb:102:in read__AMF_object'
ERROR: /usr/lib/ruby/1.8/flv/amf_string_buffer.rb:132:inread__AMF_data'
ERROR: /usr/lib/ruby/1.8/flv/amf_string_buffer.rb:112:in read__AMF_array'
ERROR: /usr/lib/ruby/1.8/flv/amf_string_buffer.rb:110:instep'
ERROR: /usr/lib/ruby/1.8/flv/amf_string_buffer.rb:110:in read__AMF_array'
ERROR: /usr/lib/ruby/1.8/flv/amf_string_buffer.rb:136:inread__AMF_data'
ERROR: /usr/lib/ruby/1.8/flv/amf_string_buffer.rb:102:in read__AMF_object'
ERROR: /usr/lib/ruby/1.8/flv/amf_string_buffer.rb:132:inread__AMF_data'
ERROR: /usr/lib/ruby/1.8/flv/meta_tag.rb:40:in after_initialize'
ERROR: /usr/lib/ruby/1.8/flv/tag.rb:56:ininitialize'
ERROR: /usr/lib/ruby/1.8/flv/stream.rb:451:in new'
ERROR: /usr/lib/ruby/1.8/flv/stream.rb:451:inread_tags'
ERROR: /usr/lib/ruby/1.8/flv/stream.rb:58:in initialize'
ERROR: /usr/lib/ruby/1.8/flvtool2/base.rb:272:innew'
ERROR: /usr/lib/ruby/1.8/flvtool2/base.rb:272:in open_stream'
ERROR: /usr/lib/ruby/1.8/flvtool2/base.rb:238:inprocess_files'
ERROR: /usr/lib/ruby/1.8/flvtool2/base.rb:225:in each'
ERROR: /usr/lib/ruby/1.8/flvtool2/base.rb:225:inprocess_files'
ERROR: /usr/lib/ruby/1.8/flvtool2/base.rb:44:in execute!'
ERROR: /usr/lib/ruby/1.8/flvtool2.rb:168:inexecute!'
ERROR: /usr/lib/ruby/1.8/flvtool2.rb:228
ERROR: /usr/bin/flvtool2:2:in `require'
ERROR: /usr/bin/flvtool2:2
Even the metadata seems corrupt.
What should I do to fix this duration?
Thanks.
EDIT:
I gave the video to ffmpeg and it recovered:
ffmpeg -i foo.flv bar.flv
However this is only a workaround and i dont get my real answer.
With the inclusion of librtmpdump into FFMPEG, this function can be done directly in ffmpeg. for the specific file you listed above. You could simply call the URL and pass the stream to a file without re-encoding it. An example would be:
ffmpeg -i rtmp://aljazeeraflashlivefs.fplive.net/aljazeeraflashlive-live/aljazeera_ara_high -vcodec copy -acodec copy ./foo.flv
this is muxing it into .flv container. if you run ffmpeg -i rtmp://aljazeeraflashlivefs.fplive.net/aljazeeraflashlive-live/aljazeera_ara_high you will see that the video has the following:
Stream #0:0: Video: h264 (Main), yuv420p(tv), 640x360 [SAR 1:1 DAR 16:9], 819 kb/s, 25 fps, 25 tbr, 1k tbn, 50 tbc
Stream #0:1: Audio: aac, 48000 Hz, stereo, fltp, 65 kb/s
So the file is an h264/AAC stream.
That should provide a compliant stream with proper timestamps.
There are a lot of questions on this topic, and I've read most of them and most of the google search results I could come up with.
When I use FFMPEG to convert a FLV to a iphone3 compatble MP4 file, it just doesn't preserver enough of the quality. Yes, I've worked the hell out of -sameq and -b and -bt settings, text just isn't readable.
Next I tried to split the video out and process it directly, using these instructions:
https://sites.google.com/site/linuxencoding/x264-encoding-guide
The problem is myplayer (via ffmpeg) was not able to determine the duration of the FLV (even though the metadata was set).
(I assume) Because of that unknown duration, when I create the MP4 file, the resulting x264 file plays through super-fast while the audio plays at the normal rate.
user#server:/tmp# mplayer -nosound -benchmark -sws 9 -vf dsize=640:480:0,scale=0:0,expand=640:480 -vo yuv4mpeg:file=>(x264 --demuxer y4m --crf 0 --preset slow --threads auto --output output.264 - 2>x264.log) 'input.flv'
MPlayer 1.0rc4-4.4.5 (C) 2000-2010 MPlayer Team
mplayer: could not connect to socket
mplayer: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.
Playing input.flv.
libavformat file format detected.
[flv # 0x1202460]Estimating duration from bitrate, this may be inaccurate
[lavf] stream 0: video (vp6f), -vid 0
[lavf] stream 1: audio (nellymoser), -aid 0
VIDEO: [VP6F] 1680x992 0bpp 1000.000 fps 33.4 kbps ( 4.1 kbyte/s)
Clip info:
audiocodecid: 6
audiodatarate: 86
audiosamplerate: 44100
audiosamplesize: 16
audiosize: 6097005
canSeekToEnd: true
datasize: 8609138
duration: 567
framerate: 2
hasAudio: true
hasCuePoints: false
hasKeyframes: true
hasMetadata: true
hasVideo: true
height: 992
lasttimestamp: 567
metadatacreator: flvtool++ (Facebook, Motion project, dweatherford)
stereo: false
totalframes: 1043
videocodecid: 4
videodatarate: 33
videosize: 2316256
width: 1680
Using (default) progressive frame mode.Opening video filter: [expand w=640 h=480]
Expand: 640 x 480, -1 ; -1, osd: 0, aspect: 0.000000, round: 1
Opening video filter: [scale w=0 h=0]
Opening video filter: [dsize=640:480:0]
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
Selected video codec: [ffvp6f] vfm: ffmpeg (FFmpeg VP6 Flash)
==========================================================================
Audio: no sound
Starting playback...
Movie-Aspect is undefined - no prescaling applied.
[swscaler # 0x7f0c738b9620]Lanczos scaler, from yuv420p to yuv420p using MMX2
VO: [yuv4mpeg] 640x480 => 641x480 Planar YV12
I have also tried specifying FPS, but no change in results
user#server:/tmp# mplayer -nosound -fps 25-benchmark -sws 9 -vf dsize=640:480:0,scale=0:0,expand=640:480 -vo yuv4mpeg:file=>(x264 --demuxer y4m --fps 25 --crf 0 --preset slow --threads auto --output output.264 - 2>x264.log) 'input.flv'
Can someone tell me how to either:
fix my split A/V processing/timing/duration issues?
improve the
quality of the FFMPEG conversion of FLV to iphone3 compatible
format?
I would suggest trying handbreak(http://handbrake.fr/), I think it can encode flvs as well as almost every other file formate I have ever tried, and I'v never had any trouble with quality.