I am using GStreamer on Windows XP to write a stream of raw (YUV) video to a sequence of AVI files. A simplified version of the pipeline I am using is shown below:
gst-launch -e -v videotestsrc pattern=smpte100 num-buffers=10 horizontal-speed=1 ! video/x-raw-yuv, format=(fourcc)UYVY, width=(int)640, height=(int)480, framerate=30/1 ! ffmpegcolorspace ! avimux ! multifilesink next-file=key-frame location="frame_%d.avi" index=1
The first problem I have is that the first file written has the file name “frame_d.avi”, i.e. the “%d” is being interpreted as “d” and so the Index is not getting substituted into the string. I am guessing that this is Unicode issue? For the moment I can work around this by modifying the source code for filesink, though I rather not do this if possible.
The second problem I have is that when I try viewing the AVI file in Windows Media Player I get the message:
“Windows Media Player cannot play the file. The Player might not support the file type or might not support the codec that was used to compress the file.”
When I try using the filesink element in the pipeline (instead of multifilesink) I can view the video in Media Player.
Looking at the file contents using a Hex editor I can see that when using multifilesink an AVI header has been written out followed by the YUV data:
5249464610030000415649204c495354f80200006864726c6176696838000000
3582000080969800000000000000000000000000000000000100000000000000
80020000e0010000000000000000000000000000000000004c49535494020000
7374726c73747268380000007669647359555932000000000000000000000000
010000001e000000000000000000000000000000000000000000000000000000
0000000073747266280000002800000080020000e00100000100100059555932
00b00400000000000000000000000000000000004a554e4b1802000004000000
0000000030306462000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000004c495354100000006f646d6c
646d6c6804000000000000004c495354040000006d6f76693030646200600900
eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80
eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80
eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80
eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80
eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80
eb80eb80eb80eb80eb80eb80eb80eb80eb80eb80eb48d289d210d292d210d292
d210d292d210d292d210d292d210d292d210d292d210d292d210d292d210d292
d210d292d210d292d210d292d210d292d210d292d210d292d210d292d210d292
d210d292d210d292d210d292d210d292d210d292d210d292d210d292d210d292
d210d292d210d292d210d292d210d292d210d292d210d292d210d292d210d292
d210d292d210d292d210d292d210d292d210d292d210d292d210d292d210d292
d210d292d210d292d210d292aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10
aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10
aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10
aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10
aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10
aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10aaa6aa10
aaa6aa1091369122913691229136912291369122913691229136912291369122
9136912291369122913691229136912291369122913691229136912291369122
9136912291369122913691229136912291369122913691229136912291369122
9136912291369122913691229136912291369122913691229136912291369122
9136912291369122913691229136912291369122913691229136912291369122
91369122913691229136912291369122913691229136912291806a806aca6ade
6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade
6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade
6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade
6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade
6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade6aca6ade
6aca6ade6aca6ade6aca6ade6aca6ade6a9251e7515a51f0515a51f0515a51f0
515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0
515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0
515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0
515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0
515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0515a51f0
515a51f0515a51f029f0296e29f0296e29f0296e29f0296e29f0296e29f0296e
29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e
29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e
29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e
29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e
29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e29f0296e
The header generated when I use filesink (and which plays correctly) looks like this:
5249464608c45d00415649204c495354f80200006864726c6176696838000000
35820000b840190100000000100000000a000000000000000100000000000000
80020000e0010000000000000000000000000000000000004c49535494020000
7374726c73747268380000007669647359555932000000000000000000000000
010000001e000000000000000a00000000600900000000000000000000000000
0000000073747266280000002800000080020000e00100000100100059555932
00b00400000000000000000000000000000000004a554e4b1802000004000000
0000000030306462000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000004c495354100000006f646d6c
646d6c68040000000a0000004c49535454c05d006d6f76693030646200600900
The data itself looks OK; apart from the fact that avimux has forced a conversion from UYUV to YUY2, which means I will need to modify avimux to support this.
Why does the header written out by multifilesink differ to the one written out by filesink, and why do these differences stop the video from playing?
Thanks in advance for any thoughts.
On the dos command promt you will need to write
location="frame_%%d.avi"
to escape the % char. Regarding your actual problem, multifilesink won't work this way for muxed content. You can use it for headerless content. avimux won't write a new header on subsequent parts. It would probably be easier to put the avimux ! filesink combo to a bin and on some event, send an eos tot he bin, set the bin to ready, change the filename and set it back to playing.
Related
I'm trying to convert an mp3 file to wav with gstreamer. Here's the pipeline:
gst-launch-1.0 filesrc location=audio.mp3 ! audio/mpeg ! mpg123audiodec ! wavenc ! filesink location=audio.wav
Also, I'd like the output to be 24 bit/48kHz
I get this error:
ERROR: from element /GstPipeline:pipeline0/GstCapsFilter:capsfilter0: Filter caps do not completely specify the output format
There was another similar thread that I saw here and tried to comment, but I had to have 50 points or whatever;)
I would make use of the bins to make your life easier. I came up with this:
gst-launch-1.0 filesrc location=in.mp3 ! decodebin ! audioresample ! audioconvert ! \
audio/x-raw,format=S24LE,rate=48000 ! wavenc ! filesink location=out.wav
Which gives me this result:
$ file out.wav
out.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 24 bit, stereo 48000 Hz
Musicbee uses opusenc to encode files into opus. I would like to encode my music files into opus in an ogg extention.
The command line arguments look like this:
--bitrate 256 --vbr --ignorelength - [outputfile]
I've tried --bitrate 256 --vbr --ignorelength - [outputfile].ogg and --bitrate 256 --vbr --ignorelength - ogg
I've looked at the documentation and I don't know how I would do this.
To encode a PCM Wave file foo.wav as an Ogg Opus file foo.ogg at 256 kb/s VBR:
opusenc --bitrate 256 foo.wav foo.ogg
VBR is the default so the --vbr option is not necessary.
You can use --ignorelength if the length in the Wave file header is wrong and you want it to assume that the audio continues to the end of the file with nothing after it, but by default it will do that if the length appears to be wrong so this should not normally be necessary.
Options such as --title and --artist may be used if you want to add tags. See opusenc --help for the available options.
If you want to convert a whole directory, use a for loop.
bash: for f in *.wav; do opusenc --bitrate 256 "$f" "${f%.wav}.ogg"; done
Windows cmd: for %F in (*.wav) do opusenc --bitrate 256 "%F" "%~nF.ogg"
In addition to Wave files, opusenc will also accept AIFF and raw PCM input, and can optionally be built to accept FLAC and Ogg/FLAC input. If you need to convert from some other format then try FFmpeg.
I have problem with recording streams using gstreamer.
I have to write audio and video separately and cut in when signal arrived. I have correctly working video, but still have problems with wav files.
Even simple pipeline in gst-launch don't work correctly. I have wave file and I am trying to split it using multifilesink:
gst-launch filesrc location=test.wav ! multifilesink location=test2%d.wav next-file=4 max-file-size=512000
But final wav files are corrupted while the same pipeline with ts files is working ok:
gst-launch-1.0 filesrc location=test.ts ! multifilesink location=test2%d.ts next-file=4 max-file-size=2000000
multifilesink doesn't know anything about the data it splits up, so it won't take care of adding headers to each of the files it writes.
The reason why your .ts files work is because it was designed to be a streaming format where each separate packet will be treated independently. Therefore, one can just 'tune in' to the stream whenever one likes. The decoder will simply look for the next packet header it finds and start decoding there (for Details have a look at MPEG TS' wiki page.
The WAV file format however was designed as pure file (and not as a streaming) format. Therefore, there's only one header at the start of the file. When you split that file up into multiple files, these headers are missing (the file contains only raw PCM data then).
To work around that issue, you can...
manually copy the .wav header from the first file to all the other ones
use programs that support PCM files and either work directly with them or convert the files (you'll have to set the channel count, sample rate and bitrate manually when opening those files though).
use another, stream oriented file format like .mp3 which comes from the same family of codecs as .ts and also uses a separate 4-byte header for each frame (Keep in mind though that MP3 is a lossy file format).
An example pipeline would be:
gst-launch filesrc location=test.wav ! wavparse ! lame ! multifilesink location=test%d.mp3 next-file=4 max-file-size=100000
If you're willing to use some scripting as well and split the task up into different gst-launch calls, I can offer you another possible way to solve your little problem:
The following script is a Linux bash script. You should be able to translate that to Windows batch script (or a C or python app if you want):
#!/bin/bash -e
# First write the buffer stream to .buff files (annotated using GStreamer's GDP format)
gst-launch -e filesrc location=test.wav ! wavparse ! gdppay ! multifilesink next-file=4 max-file-size=1000000 location=foo%05d.buff
# use the following instead for any other source (e.g. internet radio streams)
#gst-launch -e uridecodebin uri=http://url.to/stream ! gdppay ! multifilesink next-file=4 max-file-size=1000000 location=foo%05d.buff
# After we're done, convert each of the resulting files to proper .wav files with headers
for file in *.buff; do
tgtFile="$(echo "$file"|sed 's/.buff$/.wav/')"
gst-launch-0.10 filesrc "location=$file" ! gdpdepay ! wavenc ! filesink "location=$tgtFile"
done
# Uncomment the following line to remove the .buff files here, but to avoid accidentally
# deleting stuff we haven't properly converted if something went wrong, I'm not gonna do that now.
#rm *.buff
Now to what the script does:
First we're gonna use multifilesink to create a set of .buff files, each under 1MB of size (gdppay will annotate each buffer with its caps; the -e flag of gst-launch will cause it to trigger an EOS if the process gets killed prematurely which is useful if you're reading and decoding an internet stream)
The second gst-launch invocation within the for loop takes one of the .buff files, parses the GDP headers using gdpdepay (and strips them), adds a WAV header and writes the result to a .wav file.
Hope this is a solution you can live with, because I doubt there's a way to do it with one single gst-launch run.
Trying to figure out how to get gstreamer to output raw audio data as signed 32-bit floats in the range of -1 to 1.
Here's what I've got so far, but these values are unsigned and not in the scale of -1 to 1:
gst-launch-1.0 filesrc location="sound.mp3" ! mad ! audioresample ! audioconvert ! capsfilter caps="audio/x-raw, format=F32BE, rate=44100, channels=1" ! filesink location=sound.raw
Any help is greatly appreciated. Thanks.
After some testing I can confirm that GStreamer by far exceeds the range [-1,1]. Also it seems to me that there's no really simple solution to that problem if you want to use GStreamer (you could write a postprocessor that takes a raw 32bit-signed integer file and convert each 4-byte chunk to float, but that's a bit hacky).
I can however offer you an alternative solution using ffmpeg:
avconv -i /path/to/input/file.mp3 -f f32be -ac 1 /path/to/output_float.raw
I successfully played the output file using aplay:
aplay -r 44100 -f FLOAT_BE -c1 /path/to/output_float.raw
Two things you can change/add to the caps:
- audio/x-raw to audio/x-raw-float
- signed=true
The hardware on which we are working on doesnt support playing of mkv files.
So i'm required to transcode Matroska (mkv) video filea to mp4 video file.
As I have understood from the material available online on transcoding,I'm required to do the following :
separate out different streams of mkv file using matroskademux element.
decode the audio and Video streams into raw format using available mkv decoder and
supply this data to the mp4 Muxer element and re-encode to required format.
Could anyone please tell me if I applying right approach?
Any information/link on this would be very helpful.
vikram
Depending on what is in the Matroska file you might not need to decode it at all, just remux.
I assume the video for instance is H264, so just remux that.
Below is an example pipeline for gst-launch for remuxing a file with h264 and mp3.
gst-launch-0.10 -v filesrc location=$file \
! matroskademux name="demux" demux. ! h264parse ! queue \
! mp4mux name=mux ! filesink location=$file._out.mp4 demux. \
! mp3parse ! queue ! mux.`
You can also look at the Transmageddon transcoder (www.linuxrising.org) which should give you want you want.