Merge Audio Files with different Codecs - audio

i'm working on merging multiple audio merge and i'm using this command
(in below command tempTxtFile is file for all audiopath)
cmd = "-f concat -safe 0 -i " + tempTxtFile + " -c copy -preset ultrafast " + filepath;
well, because i'm using -c copy it only works if selected audios are of codec mp3,but if i will use mp3 and m4a(aac) or both m4a audios,it is preventing me from merge.
So, i now i'm using another command which is as follows(for 2 audios):
cmd = "-f concat -safe 0 -i " + tempTxtFile + " -filter_complex [0:a][1:a]" + "concat=n=2:v=0:a=1[outa] -map [outa] -c:a mp3 -preset ultrafast " + filepath;
This command showing me given error when running
Invalid file index 1 in filtergraph description [0:a][1:a]concat=n=2:v=0:a=1[outa].
This is whole log
Input #0, concat, from '/storage/emulated/0/Download/tempFile.txt':
Duration: N/A, start: 0.000000, bitrate: 117 kb/s
Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 117 kb/s
Metadata:
handler_name : SoundHandler
Invalid file index 1 in filtergraph description [0:a][1:a]concat=n=2:v=0:a=1[outa].
Right now i'm not able to do anything and don't know any working solution.

When codecs are different across files, you should feed all inputs individually and then use the concat filter e.g.
ffmpeg -i file1 -i file2 -i file3 -filter_complex concat=n=3:v=0:a=1 -c:a mp3 -vn out.mp3

Related

Decoding AAC to PCM with ffmpeg results in noise

I have a .mp4 file generated with ffmpeg as follows.
ffmpeg -y -i video_extended.mp4 -itsoffset 00:00:04.00 -i output5-1.wav -map 0:0 -map 1:0 -c:v copy -c:a aac -ac 6 -ar 48000 -b:a 128k -async 1 mixed.mp4
Playing mixed.mp4 file with ffplay is fine and there is no impact to the sound quality. Below is the output I get from ffplay when using the command ffplay -i mixed.mp4
> Input #0, mov,mp4,m4a,3gp,3g2,mj2, from
> 'mixed_h264_aac_512k_async_qp0_all_I.mp4': Metadata:
> major_brand : isom
> minor_version : 512
> compatible_brands: isomiso2avc1mp41
> encoder : Lavf58.76.100 Duration: 00:00:16.02, start: 0.000000, bitrate: 49136 kb/s Stream #0:0[0x1](und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv422p10le(progressive),
> 1920x1080, 65409 kb/s, 59.94 fps, 59.94 tbr, 11988 tbn (default)
> Metadata:
> handler_name : VideoHandler
> vendor_id : [0][0][0][0] Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, 5.1, fltp, 71 kb/s (default)
> Metadata:
> handler_name : SoundHandler
> vendor_id : [0][0][0][0] Switch subtitle stream from #-1 to #-1 vq= 1606KB sq= 0B f=0/0
Then, I decode the mixed.mp4 file back to raw PCM using the following command.
ffmpeg -i mixed.mp4 -vn -acodec pcm_s16le -f s16le -ar 48000 -ac 6 raw_audio.pcm
However, this raw_audio.pcm contains a lot of noise and ffplay output shows the following output
[s16le # 0x7f7490000c80] Estimating duration from bitrate, this may be inaccurate
Input #0, s16le, from 'separated_audio_s16.pcm':
Duration: 00:00:16.02, bitrate: 4607 kb/s
Stream #0:0: Audio: pcm_s16le, 48000 Hz, 6 channels, s16, 4608 kb/s
[pcm_s16le # 0x7f749002b940] Multiple frames in a packet.
[pcm_s16le # 0x7f749002b940] Invalid PCM packet, data has size 8 but at least a size of 12 was expected
Last message repeated 32 times
[pcm_s16le # 0x7f749002b940] Invalid PCM packet, data has size 8 but at least a size of 12 was expected
Last message repeated 11 times
Switch subtitle stream from #-1 to #-1 vq= 0KB sq= 0B f=0/0
[pcm_s16le # 0x7f749002b940] Invalid PCM packet, data has size 8 but at least a size of 12 was expected
Last message repeated 11 times
[pcm_s16le # 0x7f749002b940] Invalid PCM packet, data has size 8 but at least a size of 12 was expected
Last message repeated 11 times
[pcm_s16le # 0x7f749002b940] Invalid PCM packet, data has size 8 but at least a size of 12 was expected
Can someone please explain the issue here? Note that the ffplay command that works correctly for mixed.mp4 shows fltp as the audio format, whereas when playing the raw_audio.pcm file, it is seen as s16.
Is this a resampling issue in ffmpeg, and how can I rectify this?
I’m using ffmpeg and ffplay versions 5.0.1 in a Fedora 36 system.
Thank you.

FFmpeg: Concatenate .webm files some are video only some audio only some with both

In my case I have 3 .webm files the first one is audio only, the second one is video only, the third one is audio and video.
I want to concatenate them into a single file which shows black screen for audio only parts, video for video only parts, and plays both for the parts that have audio and video.
The video codec is VP8, the audio codec is Opus.
concat.txt contains the entries for the three files
I am using the following command to concatenate them.
ffmpeg -f concat -safe 0 -i ./concat.txt -c copy -y output.webm
This command creates the output file, when I play it it only plays the first audio only part and crashes when it reaches the video only part.
I also tried to add a dummy picture to the audio only files but the command fails when I try to concatenate.
Any and all help/critique is welcome.
Thank you!
More Info On the Input files
Input #0, matroska,webm, from 'original1.webm':
Metadata:
title : -
ENCODER : Lavf58.45.100
Duration: 00:00:09.99, start: 0.000000, bitrate: 34 kb/s
Stream #0:0: Audio: opus, 48000 Hz, stereo, fltp (default)
Metadata:
DURATION : 00:00:09.990000000
Input #1, matroska,webm, from 'original2.webm':
Metadata:
title : -
ENCODER : Lavf58.45.100
Duration: 00:00:09.75, start: 0.000000, bitrate: 954 kb/s
Stream #1:0: Video: vp8, yuv420p(tv, bt470bg/unknown/unknown, progressive), 1680x1050, SAR 1:1 DAR 8:5, 1k tbr, 1k tbn, 1k tbc (default)
Metadata:
DURATION : 00:00:09.754000000
Input #2, matroska,webm, from 'original3.webm':
Metadata:
title : -
ENCODER : Lavf58.45.100
Duration: 00:00:10.02, start: 0.000000, bitrate: 912 kb/s
Stream #2:0: Audio: opus, 48000 Hz, stereo, fltp (default)
Metadata:
DURATION : 00:00:10.023000000
Stream #2:1: Video: vp8, yuv420p(tv, bt470bg/unknown/unknown, progressive), 1680x1050, SAR 1:1 DAR 8:5, 1k tbr, 1k tbn, 1k tbc (default)
Metadata:
DURATION : 00:00:09.965000000
All files to be concatenated must have the same attributes and stream order.
Add black video to audio only file:
ffmpeg -i audio.webm -f lavfi -i color=s=1680x1050 -r 1000 -map 0 -map 1 -c:a copy -c:v libvpx -shortest output1.webm
Add silent audio to video only file:
ffmpeg -f lavfi -i anullsrc=r=48000:cl=stereo -i video.webm -map 0 -map 1 -c:a libopus -c:v copy -shortest output2.webm
Make input.txt with the following contents:
file 'output1.webm'
file 'output2.webm'
file 'original3.webm'
Concatenate with the concat demuxer:
ffmpeg -f concat -safe 0 -i concat.txt -c copy output.webm

ffmpeg how to attach & extract text/data file to audio or video stream?

I have:
1/ AUDIO.m4a stream
2/ a cover album jpeg
3/ an UTF8 text file
I wish to bind all of them into a mkv/mp4 container.
To bind the audio & image I can
ffmpeg -y -i "AUDIO.mp4" -attach COVER.jpg -metadata:s mimetype="image/jpeg" -c:a copy "AUDIO_COPY_WITH_COVER.mka"
Further to bind the text file
ffmpeg -y -i "AUDIO_COPY_WITH_COVER.mka" -c copy -attach "TEXT.txt" -metadata:s:2 mimetype=application/octet-stream "AUDIO_JPEG_TEXT.mkv"
If I check I get:
Input #0, matroska,webm, from 'AUDIO_JPEG_TEXT.mkv':
Metadata:
MINOR_VERSION : 512
COMPATIBLE_BRANDS: M4A isomiso2
MAJOR_BRAND : M4A
ENCODER : Lavf58.45.100
Duration: 00:36:10.36, start: 0.000000, bitrate: 67 kb/s
Stream #0:0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 320x240 [SAR 1:1 DAR 4:3], 1k tbr, 1k tbn, 1k tbc (default)
Metadata:
FILENAME : COVER.jpg
MIMETYPE : image/jpeg
DURATION : 00:00:00.000000000
Stream #0:1: Audio: aac (HE-AAC), 44100 Hz, stereo, fltp (default)
Metadata:
HANDLER_NAME : SoundHandler
MIMETYPE : image/jpeg
DURATION : 00:36:10.358000000
Stream #0:2: Attachment: none
Metadata:
filename : TEXT.txt
mimetype : application/octet-stream
Question:
1/ How do I extract my text file?
ffmpeg -i "AUDIO_JPEG_TEXT.mkv" -map 0:t -metadata:s:2 mimetype=application/octet-stream "my text.txt"
I get the error:
Unable to find a suitable output format for 'my text.txt'
my text.txt: Invalid argument
**2/If I replace the command with **
ffmpeg -y -i "AUDIO_COPY_WITH_COVER.mka" -c copy -attach "TEXT.txt" -metadata:t:2 mimetype=application/octet-stream "AUDIO_JPEG_TEXT.mkv"
Excuting
ffmpeg -i "AUDIO_JPEG_TEXT.mkv"
get error
EBML header parsing failed
AUDIO_JPEG_TEXT.mkv: Invalid data found when processing input
2/ How can I write in one command the 3 attachments(audio,img,document)?
Thanks
To attach in one command,
ffmpeg -y -i "AUDIO.mp4" -attach COVER.jpg -metadata:s:1 mimetype="image/jpeg" -attach "TEXT.txt" -metadata:s:2 mimetype=application/octet-stream -c copy "AUDIO_JPEG_TEXT.mkv"
To extract text,
ffmpeg -dump_attachment:t:0 out.txt -i AUDIO_JPEG_TEXT.mkv

ffmpeg change the order of the output

i try to change the order of the output of 3 inputs (2 audio + 1 video)
this is my command:
/usr/bin/ffmpeg -async 1 \
-f pulse -i alsa_output.pci-0000_00_1b.0.analog-stereo.monitor \
-f pulse -i alsa_input.pci-0000_00_1b.0.analog-stereo \
-f x11grab -video_size 1920x1080 -framerate 8 -i :0.0 \
-filter_complex amix=inputs=2 \
-c:a aac -b:a 128k \
-c:v h264_nvenc -b:v 1500k -maxrate 1500k -minrate 1500k \
-override_ffserver -g 16 http://10.100.102.109:8090/feed1.ffm
this command works but, the first output is audio , therefore my third app cant view this output
this is my output:
Stream mapping:
Stream #0:0 (pcm_s16le) -> amix:input0 (graph 0)
Stream #1:0 (pcm_s16le) -> amix:input1 (graph 0)
amix (graph 0) -> Stream #0:0 (aac)
Stream #2:0 -> #0:1 (rawvideo (native) -> h264 (h264_nvenc))
Press [q] to stop, [?] for help
-async is forwarded to lavfi similarly to -af aresample=async=1:min_hard_comp=0.100000:first_pts=0.
Last message repeated 1 times
Output #0, ffm, to 'http://10.100.102.109:8090/feed1.ffm':
Metadata:
creation_time : now
encoder : Lavf57.83.100
Stream #0:0: Audio: aac (LC), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
encoder : Lavc57.107.100 aac
Stream #0:1: Video: h264 (h264_nvenc) (Main), bgr0, 1920x1080, q=-1--1, 1500 kb/s, 8 fps, 1000k tbn, 8 tbc
Metadata:
encoder : Lavc57.107.100 h264_nvenc
Side data:
cpb: bitrate max/min/avg: 1500000/0/1500000 buffer size: 3000000 vbv_delay: -1
****how can i replace the output that the video will be first?****
(when i do this command with 1 audio and 1 video inputs, the output is fine, the video is first , and the third part App can view it)
i spent a lot of hours on it please help me.
tnx a lot ...
In the absence of mapping, output streams from complex filtergraphs will be ordered before other streams. So, add a label to the filter_complex output and map in the order required.
Use
/usr/bin/ffmpeg -async 1 \
-f pulse -i alsa_output.pci-0000_00_1b.0.analog-stereo.monitor \
-f pulse -i alsa_input.pci-0000_00_1b.0.analog-stereo \
-f x11grab -video_size 1920x1080 -framerate 8 -i :0.0 \
-filter_complex "amix=inputs=2[a]" \
-map 2:v -map '[a]' \
-c:a aac -b:a 128k \
-c:v h264_nvenc -b:v 1500k -maxrate 1500k -minrate 1500k \
-override_ffserver -g 16 http://10.100.102.109:8090/feed1.ffm

How to replace the video track of a part of a video file?

I have an mp4 file like this(same format but longer):
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'N1.2.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42mp41
creation_time : 2018-10-31T13:44:21.000000Z
Duration: 00:28:54.21, start: 0.000000, bitrate: 10295 kb/s
Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080, 9972 kb/s, 50 fps, 50 tbr, 50k tbn, 100 tbc (default)
Metadata:
creation_time : 2018-10-31T13:44:21.000000Z
handler_name : ?Mainconcept Video Media Handler
encoder : AVC Coding
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 317 kb/s (default)
Metadata:
creation_time : 2018-10-31T13:44:21.000000Z
handler_name : #Mainconcept MP4 Sound Media Handler
I also have another video file that is 3 minutes long. and has no audio. What is the fastest way to encode the other video in a way that it is encoded like my main video and then replace the last three minutes of the video track of my original video with this?
In other words.
I have video A that is 1 hour long. With the encoding shown above.
I have video B that is 3 minutes long with no audio. with a random encoding.
I want to have video C with the same encoding and same audio as A. But it's video track would be the first 57 minutes of A + B(which is 3 minutes).
I want to do this as fast as possible so I would like to not re encode A.
I know how to concatenate two videos, I use this command:
ffmpeg -f concat -i files.txt -c copy res.mp4
Make end video using parameters of main video:
ffmpeg -i videob.mp4 -f lavfi -i anullsrc=sample_rate=48000:channel_layout=stereo -filter_complex "[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1,format=yuv420p,fps=50[v]" -map "[v]" -map 1:a -c:v libx264 -profile:v main -c:a aac -video_track_timescale 50000 -shortest videob2.mp4
Get duration of main video:
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 main.mp4
Make files.txt which is needed for concat demuxer:
file 'main.mp4'
outpoint 3420
file 'videob2.mp4'
In this example outpoint is main video duration minus end video duration.
Concatenate:
ffmpeg -f concat -i files.txt -i main.mp4 -map 0:v -map 1:a -c copy -shortest output.mp4

Resources