has anybody gotten gstreamer to successfully pipe it's video output into ffmpeg?
I've tried playing with /dev/stdout and I keep getting errors:
gst-launch -e v4l2src device=/dev/video0 ! 'video/x-raw-yuv,width=1920,height=1080,framerate=5/1' ! nv_omx_h264enc quality-level=2 ! mp4mux ! filesink location=/dev/stdout \
| ffmpeg -y -i - -codec copy -f flv test.flv
...
[aac # 0xebc4c0] Could not find codec parameters for stream 0 (Audio: aac (Main), 7.1, fltp, 1351 kb/s): unspecified sample rate
Consider increasing the value for the 'analyzeduration' and 'probesize' options
pipe:: could not find codec parameters
Input #0, aac, from 'pipe:':
Duration: N/A, bitrate: 1351 kb/s
Stream #0:0: Audio: aac (Main), 7.1, fltp, 1351 kb/s
[flv # 0xec9280] sample rate not set
Output #0, flv, to 'test.flv':
Stream #0:0: Audio: aac, 7.1, 1351 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
ubuntu#tegra-ubuntu:~$
Running the commands separately (replacing /dev/stdout with a file) works fine.
If you got it to work and can share how you did it, that would be great.
Thanks.
You can not use MP4 as a streaming format, as it cannot be parsed linear, e.g. without random access. Therefore it works with files, but not via a pipe.
Replacing the container format with a format that can be streamed should do the trick:
gst-launch -e v4l2src device=/dev/video0 \
! 'video/x-raw-yuv,width=1920,height=1080,framerate=5/1' \
! nv_omx_h264enc quality-level=2 ! matroskamux \
! filesink location=/dev/stdout \
| ffmpeg -y -i - -codec copy -f flv test.flv
Related
With "wrong total duration" I mean a total duration different from the sum of individual duration of audio files.
sum_duration_files != duration( concatenation of files )
In particular I am concatenating 2 OGG audio files with this command
ffmpeg -safe 0 -loglevel quiet \
-f concat -segment_time_metadata 1 -i {m3u_file_name} \
-vf select=concatdec_select \
-af aselect=concatdec_select,aresample=async=1 \
{ogg_file_name}
And I get the following
# Output of: ffprobe <FILE>.ogg
======== files_in
Input #0, ogg, from 'f1.ogg':
Duration: 00:00:04.32, start: 0.000000, bitrate: 28 kb/s
Stream #0:0: Audio: opus, 48000 Hz, mono, fltp
Input #0, ogg, from 'f2.ogg':
Duration: 00:00:00.70, start: 0.000000, bitrate: 68 kb/s
Stream #0:0: Audio: vorbis, 44100 Hz, mono, fltp, 160 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
Note durations: 4.32 and 0.7 sec
And this is the output file.
========== files out (concatenate of files_in)
Input #0, ogg, from 'f_concat_v1.ogg':
Duration: 00:00:04.61, start: 0.000000, bitrate: 61 kb/s
Stream #0:0: Audio: vorbis, 48000 Hz, mono, fltp, 80 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
Duration: 4.61 sec
As 4.61 sec != 4.32 + 0.7 sec I have a problem.
The issue here is using a wrong concatenation approach for these files. As FFmpeg wiki article suggests, file-level concatenation (-f concat) requires all files in the listing to have the exact same codec parameters. In your case, only # of channels (mono) and sample format (flt) are common between them. On the other hand, codec (opus vs. vorbis) and sampling rate (48000 vs. 44100) are different.
-f concat grabs the first set of parameters and runs with it. In your case, it uses 48000 S/s for all the files. Although the second file is 44100 S/s, it assumes 48k (so it'll play it faster than it is). I don't know how the difference in the codec played out in the output.
So, a standard approach is to use -filter_complex concat=a=1:v=1:n=2 with these files given as separate inputs.
Out of curiosity, have you listen to the wrong-duration output file? [edit: never mind, your self-answer indicates one of them is a silent track]
I don't know WHY it happens, but I know how to avoid the problem in my particular case.
My case:
I am mixing (concatenating) different audio files generated by one single source with silence files generated by me.
Initially I generated the silence files with
# x is a float from python
ffmpeg -f lavfi -i anullsrc=r=44100:cl=mono -t {x:2.1f} -q:a 9 -acodec libvorbis silence-{x:2.1f}.ogg
Trying to resolve the issue I re-created those silences with the SAME parameters than the audios I was mixing with, that is (mono at 48Khz):
ffmpeg -f lavfi -i anullsrc=r=48000:cl=mono -t {x:2.1f} -c:a libvorbis silence-{x:2.1f}.ogg
And now ffprobe shows the expected result.
========== files out (concatenate of files_in)
Input #0, ogg, from 'f_concat_v2.ogg':
Duration: 00:00:05.02, start: 0.000000, bitrate: 56 kb/s
Stream #0:0: Audio: vorbis, 48000 Hz, mono, fltp, 80 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
Duration: 5.02 = 4.32 + 0.70
If you want to avoid problems when concatenating silence with other sounds, do create the silence with the SAME parameters than the sound you will mix with (mono/stereo and Hz)
==== Update 2022-03-08
Using the info provided by #kesh I have recreated the silent ogg files using
ffmpeg -f lavfi -i anullsrc=r=48000:cl=mono -t 5.8 -c:a libopus silence-5.8.ogg
And now the
ffmpeg -safe 0 -f concat -segment_time_metadata 1
-i {m3u_file_name}
-vf select=concatdec_select
-af aselect=concatdec_select,aresample=async=1 {ogg_file_name}
Doesn't throw this error anymore (multiple times).
[opus # 0x558b2c245400] Error parsing the packet header.
Error while decoding stream #0:0: Invalid data found when processing input
I must say that the error was not creating (for me) any problem, because the output was what I expected, but now I feel better without it.
I use this cmd convert s16le to pcmu8, but will lost header info.
ffmpeg -i s16le.wav -f u8 pcmu8.wav
ffmpeg -i pcmu8.wav
# pcmu8.wav: Invalid data found when processing input
I want known, how add this header info into pcmu8.wav?
It should be this:
ffmpeg -i pcmu8.wav
#Input #0, wav, from 'pcmu8.wav':
# Duration: 00:13:39.20, bitrate: 64 kb/s
# Stream #0:0: Audio: pcm_u8 ([1][0][0][0] / 0x0001), 8000 Hz, mono, u8, 64 kb/s
Your first command is outputting to a raw bitstream, not a WAV, so adding a header won't help. Instead use
ffmpeg -i s16le.wav -c:a pcm_u8 pcmu8.wav
I am able to stream with ffmpeg an mp4 file with h264 encoded video and aac encoded audio to flash flv output. The command I used is:
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -c copy -f flv rtmp://192.168.3.64:1935/main/stream0
When I am trying to use the tee option to duplicate the output I am failing with an error. This is the command I use:
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -map 0 -c copy -f tee "[f=flv]rtmp://192.168.3.64:1935/main/stream0|[f=flv]rtmp://192.168.3.64:1935/main/stream1"
However, it fails. What I am missing? The output I have from ffmpeg is:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'bigbuckbunny_HD_60fps.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf54.29.104
Duration: 00:10:34.58, start: 0.000000, bitrate: 4279 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 4141 kb/s, 60 fps, 60 tbr, 90k tbn, 120 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
Metadata:
handler_name : SoundHandler
[flv # 0x24607a0] Tag avc1 incompatible with output codec id '28' ([7][0][0][0])
[tee # 0x2365260] Slave '[f=flv]rtmp://192.168.3.64:1935/mainconcept/stream0': error writing header: Invalid data found when processing input
[tee # 0x2365260] Slave muxer #0 failed, aborting.
Could not write header for output file #0 (incorrect codec parameters ?): Invalid data found when processing input
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Last message repeated 1 times
According to ffmpeg -f tee refuses to do anything useful add -tag:v 7 (or -vtag 7, same thing):
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -map 0 -c copy -tag:v 7 -f tee "[f=flv]rtmp://192.168.3.64:1935/main/stream0|[f=flv]rtmp://192.168.3.64:1935/main/stream1"
If you get error Tag mp4a incompatible with output codec id '86018' add -tag:a 10 / -atag 10:
ffmpeg -re -i bigbuckbunny_HD_60fps.mp4 -map 0 -c copy -tag:v 7 -tag:a 10 -f tee "[f=flv]rtmp://192.168.3.64:1935/main/stream0|[f=flv]rtmp://192.168.3.64:1935/main/stream1"
Related bug report is #6258: tee muxer fails on stream copy.
I want to receive a RTP Stream and send the raw data received in it over TCP / UDP socket. For this i am trying following commands.
I am sending the RTP stream using following command.
ffmpeg -re -i hello.wav -ar 8000 -f mulaw -f rtp rtp://127.0.0.1:1234
Receiver to re transmit the stream over TCP / UDP socket.
ffmpeg -i rtp://127.0.0.1:1234 -f mulaw tcp://127.0.0.1:5555 -hide_banner
A Player to play this Socket stream to verify.
ffplay tcp://127.0.0.1:5555?listen
My second command shows that its receiving data and transmitting the data to tcp over 5555 port.
Input #0, rtp, from 'rtp://127.0.0.1:1234':
Duration: N/A, start: 0.000000, bitrate: 64 kb/s
Stream #0:0: Audio: pcm_mulaw, 8000 Hz, mono, s16, 64 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (pcm_mulaw (native) -> pcm_mulaw (native))
Press [q] to stop, [?] for help
Output #0, mulaw, to 'tcp://127.0.0.1:5555':
Metadata:
encoder : Lavf58.29.100
Stream #0:0: Audio: pcm_mulaw, 8000 Hz, mono, s16, 64 kb/s
Metadata:
encoder : Lavc58.54.100 pcm_mulaw
But the third command does not receive anything, even i tried dumping the response into a file using FFMPEG in command three but same results.
What am i doing wrong, Please suggest the correct commands using FFMPEG.
Following three commands worked for me.
ffmpeg -re -i music.wav -ar 8000 -f mulaw -f rtp rtp://127.0.0.1:1236
ffmpeg -i rtp://127.0.0.1:1236 -f wav tcp://127.0.0.1:1256
ffplay tcp://127.0.0.1:1256?listen -ar 8000
I am able to send file as RTP, convert it to raw wav and send it over socket and then play it from that socket.
Is there any way to use ffmpeg to accurately break audio files into smaller files of a specific file size, or pull a specific number of samples from a file?
I'm working with a speech-to-text API that needs audio chunks in exactly 160,000 bytes, or 80,000 16-bit samples.
I have a video stream, and I have an ffmpeg command to extract audio from it:
ffmpeg -i "rtmp://MyFMSWorkspace/ingest/test/mp4:test_1000 live=1" -ar 16000 -f segment -segment_time 10 out%04d.wav
So now I have ~10 second audio chunks with a sample rate of 16 kHz. Is there any way to break this into exactly 160kb, 5 second files using ffmpeg?
I tried this:
ffmpeg -t 00:00:05.00 -i out0000.wav outCropped.wav
But the output was this:
Input #0, wav, from 'out0000.wav':
Metadata:
encoder : Lavf56.40.101
Duration: 00:00:10.00, bitrate: 256 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, 1 channels, s16, 256 kb/s
Output #0, wav, to 'outCropped.wav':
Metadata:
ISFT : Lavf56.40.101
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, mono, s16, 256 kb/s
Metadata:
encoder : Lavc56.60.100 pcm_s16le
Stream mapping:
Stream #0:0 -> #0:0 (pcm_s16le (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
size= 156kB time=00:00:05.00 bitrate= 256.1kbits/s
but now the size is 156kb
EDIT:
My finished command is:
ffmpeg -i "url" -map 0:1 -af aresample=16000,asetnsamples=16000 -f segment -segment_time 5 -segment_format sw out%04d.sw
That output looks perfectly right. That ffmpeg size is expressed in KiB although it says kB. 160000 bytes = 156.25 kB + some header data. ffmpeg shows size with fractional part hidden. If you want a raw file, with no headers, output to .raw instead of .wav.
For people converting video files to MP3s split into 30 minute segments:
ffmpeg -i "something.MP4" -q:a 0 -map a -f segment -segment_time 1800 FileNumber%04d.mp3
The -q option can only be used with libmp3lame and corresponds to the LAME -V option (source)