I want to convert raw audio(binary) to audio file(mp3, wav etc) with same audio info as originals'.
Here's video(mp4) file that has audio stream's, and following is the audio stream info pulled out from ffmpeg.
Stream #0:1(eng): Audio: adpcm_ima_wav (ms[0][17] / 0x1100736D), 32000 Hz, 2 channels, s16p, 256 kb/s (default)
I used,
ffmpeg.exe -f s16le -ar 32000 -ac 1 -i raw_audio.raw -acodec copy output.wav
Seems converting process is finished okay, but the problem is, if I listen the output.wav, there's the big noise from output wav file. Also, it's not the same audio from original video.
I tried specifying "adpcm_ima_wav" codec with "-f" switch, but it doesn't work.
Any suggenstion please?
by the way I know how to extract audio from video with ffmpeg, I just want to convert RAW audio binary data to .WAV or .MP3
(ffmpeg.exe -f test.mp4 -map 0:a:0 audio.mp3)
Related
I am converting MP3 to Webm and the MP3 file includes a video stream for the cover art.
ffprobe filename.mp3
...
Stream #0:0: Audio: mp3, 22050 Hz, stereo, fltp, 64 kb/s
Stream #0:1: Video: mjpeg (Baseline), yuvj444p(pc, bt470bg/unknown/unknown), 300x300, 90k tbr, 90k tbn, 90k tbc (attached pic)
Using ffmpeg with libopus codec to convert the file causes a VP9 video stream that doesn't work well. I noticed:
VLC Player doesn't show the duration and the progress scrubber doesn't move when playing.
Android Media Player doesn't show image for the cover art of the track.
ffprobe filename.webm
...
Input #0, matroska,webm, from 'webm_bad/B01___01_Matthew_____ENGWEBN2DA.webm':
...
Stream #0:0: Video: vp9 (Profile 1), yuv444p(tv, progressive), 300x300, SAR 1:1 DAR 1:1, 1k tbr, 1k tbn, 1k tbc (default)
If I tried to use -vcodec copy option, then I get this error:
[webm # 0x7fdddf028e00] Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM.
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:1 --
Does WebM support cover art? If so, how do I transfer the MP3 cover art over using ffmpeg (or other tool)?
No, WebM does not support cover art.
From the FAQ:
The WebM file structure is based on the Matroska media container.
The cover art in a Matroska container is stored in an attachment:
Attachment Elements can be used to store related cover art, [...]
A WebM container does not support attachments:
Attachment
WebM Support
Element Name
Description
Unsupported
Attachments
Contain attached files.
Unsupported
AttachedFile
An attached file.
Unsupported
FileDescription
A human-friendly name for the attached file.
Unsupported
FileName
Filename of the attached file.
Unsupported
FileMimeType
MIME type of the file.
Unsupported
FileData
The data of the file.
Unsupported
FileUID
Unique ID representing the file, as random as possible.
Unsupported
FileReferral
A binary value that a track/codec can refer to when the attachment is needed.
Unsupported
FileUsedStartTime
DivX font extension
Unsupported
FileUsedEndTime
DivX font extension
Maybe you can consider using a different container. Opus audio streams, like the ones in a WebM container, are supported by other containers:
Opus was originally specified for encapsulation in Ogg containers
If you still want to use WebM, an alternative would be to create a video stream with a still image along with an audio stream. The FFmpeg wiki covers that topic in the Slideshow page. Combining that with this answer, which explains how to extract the cover art of an MP3 file, you could do the following:
ffmpeg -i filename.mp3 -an -c:v copy cover.jpeg
ffmpeg -loop 1 -i cover.jpeg -i filename.mp3 -c:v libvpx-vp9 -c:a libopus -b:a 64k -shortest filename.webm
64k is the bitrate that you show in the output of ffprobe.
The encoding might be slow with the second command. The Encode/Youtube page in the FFmpeg wiki shows an example command to create a video with an still image that uses the -framerate 2 option, like this:
ffmpeg -loop 1 -framerate 2 -i cover.jpeg -i filename.mp3 -c:v libvpx-vp9 -c:a libopus -b:a 64k -shortest filename.webm
For some reason I do not know, the output video of that last command cannot be reproduced by my VLC and the player crashes. 6 was the minimum -framerate that did not crash my player, so be careful.
I'm working with multichannel audio files (higher-order ambisonics), that typically have at least 16 channels.
Sometimes I'm only interested in a subset of the audiochannels (e.g. the first 25 channels of a file that contains even more channels).
For this I have a script like the following, that takes a multichannel input file, an output file and the number of channels I want to extract:
#!/bin/sh
infile=$1
outfile=$2
channels=$3
channelmap=$(seq -s"|" 0 $((channels-1)))
ffmpeg -y -hide_banner \
-i "${infile}" \
-filter_complex "[0:a]channelmap=${channelmap}" \
-c:a libopus -mapping_family 255 -b:a 160k -sample_fmt s16 -vn -f webm -dash 1 \
"${outfile}"
The actual channel extraction is done via the channelmap filter, that is invoked with something like -filter:complex "[0:a]channelmap=0|1|2|3"
This works great with 1,2,4 or 16 channels.
However, it fails with 9 channels, and 25 and 17 (and generally anything with >>16 channels).
The error I get is:
$ ffmpeg -y -hide_banner -i input.wav -filter_complex "[0:a]channelmap=0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16" -c:a libopus -mapping_family 255 -b:a 160k -sample_fmt s16 -vn -f webm -dash 1 output.webm
Input #0, wav, from 'input.wav':
Duration: 00:00:09.99, bitrate: 17649 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 25 channels, s16, 17640 kb/s
[Parsed_channelmap_0 # 0x5568874ffbc0] Output channel layout is not set and cannot be guessed from the maps.
[AVFilterGraph # 0x5568874fff40] Error initializing filter 'channelmap' with args '0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16'
Error initializing complex filters.
Invalid argument
So ffmpeg cannot guess the channel layout for a 17 channel file.
ffmpeg -layouts only lists channel layouts with 1,2,3,4,5,6,7,8 & 16.
However, I really don't care about the channel layout. The entire concept of "channel layout" is centered around the idea, that each audio channel should go to a different speaker.
But my audio channels are not speaker feeds at all.
So I tried providing explicit channel layouts, with something like -filter_complex "[0:a]channelmap=map=0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16:channel_layout=unknown", but this results in an error when parsing the channel layout:
$ ffmpeg -y -hide_banner -i input.wav -filter_complex "[0:a]channelmap=map=0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16:channel_layout=unknown" -c:a libopus -mapping_family 255 -b:a 160k -sample_fmt s16 -vn -f webm -dash 1 output.webm
Input #0, wav, from 'input.wav':
Duration: 00:00:09.99, bitrate: 17649 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 25 channels, s16, 17640 kb/s
[Parsed_channelmap_0 # 0x55b60492bf80] Error parsing channel layout: 'unknown'.
[AVFilterGraph # 0x55b604916d00] Error initializing filter 'channelmap' with args 'map=0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16:channel_layout=unknown'
Error initializing complex filters.
Invalid argument
I also tried values like any, all, none, 0x0 and 0xFF with the same result.
I tried using mono (as the channels are kind-of independent), but ffmpeg is trying to be clever and tells me that a mono layout must not have 17 channels.
I know that ffmpeg can handle multi-channel files without a layout.
E.g. converting a 25-channel file without the -filter_complex "..." works without problems, and ffprobe gives me an unknown channel layout.
So: how do I tell ffmpeg to just not care about the channel_layout when creating an output file that only contains a subset of the input channels?
Based on Audio Channel Manipulation you could try splitting into n separate streams the amerge them back together:
-filter_complex "\
[0:a]pan=mono|c0=c0[a0];\
[0:a]pan=mono|c0=c1[a1];\
[0:a]pan=mono|c0=c2[a2];\
[0:a]pan=mono|c0=c3[a3];\
[0:a]pan=mono|c0=c4[a4];\
[0:a]pan=mono|c0=c5[a5];\
[0:a]pan=mono|c0=c6[a6];\
[0:a]pan=mono|c0=c7[a7];\
[0:a]pan=mono|c0=c8[a8];\
[0:a]pan=mono|c0=c9[a9];\
[0:a]pan=mono|c0=c10[a10];\
[0:a]pan=mono|c0=c11[a11];\
[0:a]pan=mono|c0=c12[a12];\
[0:a]pan=mono|c0=c13[a13];\
[0:a]pan=mono|c0=c14[a14];\
[0:a]pan=mono|c0=c15[a15];\
[0:a]pan=mono|c0=c16[a16];\
[a0][a1][a2][a3][a4][a5][a6][a7][a8][a9][a10][a11][a12][a13][a14][a15][a16]amerge=inputs=17"
Building on the answer from #aergistal, and working with an mxf file with 10 audio streams, I had to modify the filter in order to specify the input to every pan filter. Working with "pan=mono" it only uses one channel identified as c0
-filter_complex "\
[0:a:0]pan=mono|c0=c0[a0];\
[0:a:1]pan=mono|c0=c0[a1];\
[0:a:2]pan=mono|c0=c0[a2];\
[0:a:3]pan=mono|c0=c0[a3];\
[0:a:4]pan=mono|c0=c0[a4];\
[0:a:5]pan=mono|c0=c0[a5];\
[0:a:6]pan=mono|c0=c0[a6];\
[0:a:7]pan=mono|c0=c0[a7];\
[0:a:8]pan=mono|c0=c0[a8];\
[0:a:9]pan=mono|c0=c0[a9];\
[a0][a1][a2][a3][a4][a5][a6][a7][a8][a9]amerge=inputs=10"
I need to capture an audio/video rtsp stream uncompressed in a file from ipcamera. Audio (pcm_alaw) and video (h264) must be synchronized. It is necessary that the file does not get corrupted if the camera loses the connection for a few moments (mp4).
At the moment I use the command below, but the ts codec does not support pcm_alaw and therefore the audio is not heard:
ffmpeg -stimeout 2000000 -rtsp_transport tcp -i rtsp://admin:1234#192.168.5.22/h264 -c:v copy -c:a copy -f mpegts -y main.ts
I use the mpegts codec because I need to check the duration of the capture in real time with the command:
ffprobe -i /home/pi/NAS/main.mov -show_entries format=duration -v quiet -of csv="p=0"
If i use mkv or avi its output would be:
N/A
The verification of the duration is important because I capture files of about 3 hours and at my choice I perform some data while the capture is in progress. I prefer not to compress the audio because I have often noticed some asynchrony with respect to the video when cutting.
Thank you.
Instead of -c:a copy you can use -c:a aac or -c:a mp3 to convert the audio stream before you save it.
MPEG-TS h264 is only compatible with mp3 or aac (source).
If I have a video file with 1 video streams, 2 DTS audio streams, and 2 subtitle streams, can I convert a DTS stream to ac3 and mux it into a file with a single command?
Currently I used a command like this (stream 0:1 is DTS-HD) to extract the audio and convert it to AC3, then I have to manually mux it back in using -map. Is there a way to cut out that 2nd command and just convert and mux in the new stream to a new file?
ffmpeg -y -i "media.mkv" -map 0:1 -c:a ac3 -b:a 640k newmedia.mkv
ALSO: The DTS streams are 5.1 surround sound. Do I have to do anything special to preserve those channels, or will they automatically convert over?
Use
ffmpeg -y -i "media.mkv" -map 0 -c copy -c:a:0 ac3 -b:a:0 640k newmedia.mkv.
In the command above, the first output audio stream is encoded to AC3, with a bitrate set for it. All other streams are copied.
If the encoder supports the channel count and layout then they will be preserved. AC3 does, IIRC.
I have the camera-like device that produces video stream and passes it into my Windows-based machine via USB port.
Using the command:
ffmpeg -y -f vfwcap -i list
I see that (as expected) FFmpeg finds the input stream as stream #0.
Using the command:
ffmpeg -y -f vfwcap -r 25 -i 0 c:\out.mp4
I can successfully save the input stream into the file.
From the log I see:
Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 240x320, 25 tbr, 1k tbn, 25 tbc
No pixel format specified, yuv422p for H.264 encoding chosen.
So, my input format is transcoded to yuv422p.
My question:
How can I cause FFmpeg to save my input video stream into out.mp4 WITHOUT transcoding - actually, to copy input stream to output file as close as possible, with the same format?
How can I cause ffmpeg to save my input videostream into out.mp4 WITHOUT transcoding
You can not. You can stream copy the rawvideo from vfwcap, but the MP4 container format does not support rawvideo. You have several options:
Use a different output container format.
Stream copy to rawvideo then encode.
Use a lossless encoder (and optionally re-encode it after capturing).
Use a different output container format
This meets your requirement of saving your input without re-encoding.
ffmpeg -f vfwcap -i 0 -codec:v copy rawvideo.nut
rawvideo creates huge file sizes.
Stream copy to rawvideo then encode
This is the same as above, but the rawvideo is then encoded to a more common format.
ffmpeg -f vfwcap -i 0 -codec:v copy rawvideo.nut
ffmpeg -i rawvideo.nut -codec:v libx264 -crf 23 -preset medium -pix_fmt yuv420p -movflags +faststart output.mp4
See the FFmpeg and x264 Encoding Guide for more information about -crf, -preset, and additional detailed information on creating H.264 video.
-pix_fmt yuv420p will use a pixel format that is compatible with dumb players like QuickTime. Refer to colorspace and chroma subsampling for more info.
-movflags +faststart relocates the moov atom which allows the video to begin playback before it is completely downloaded by the client. Useful if you are hosting the video and users will view it in their browser.
Use a lossless encoder
Using huffyuv:
ffmpeg -f vfwcap -i 0 -codec:v huffyuv lossless.mkv
Using lossless H.264:
ffmpeg -f vfwcap -i 0 -codec:v libx264 -qp 0 lossless.mp4
Lossless files can be huge, but not as big as rawvideo.
Re-encoding the lossless output is the same as re-encoding the rawvideo.