How to merge mp4 audio dash fragment with another audio - audio

I have 1 audio file from dash stream
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'file_191282-377206_header.mp4': Metadata:
major_brand : iso6
minor_version : 1
compatible_brands: mp42dashmsdhmsixiso6avc1isom
creation_time : 2016-04-29T11:04:26.000000Z Duration: 00:00:30.02, start: 14.997333, bitrate: 49 kb/s
Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 48 kb/s (default)
Also in exiftool output:
Movie Data Size : 180193
Movie Data Offset : 6388
I try to merge with another audio and save metadata info like Movie Data Size/Offset and start/duration time.
I try with ffmpeg/MP4Box commands like:
MP4Box -new -add file_191282-377206_header.mp4 -add out000.mp4
ffmpeg -i file_191282-377206_header.mp4 -i out000.mp4 -codec copy -shortest output.mp4
ffmpeg -i file_191282-377206_header.mp4 -i out000.mp4 -filter_complex amerge -ac 2 -c:a aac output.mp4
All the time information erased or changed.
So question is how to merge 2 audio files inside mp4 and not change Movie Size/Offset and start/duration time?

Try to merge the actual audio (AAC) not the media container (MP4).
So extract the AAC from each media file, then merge those audios.
Finalise by putting the merged audio back into a new MP4 output.

Related

Merge two MP3 files and maintain high bitrate and original properties of MP3s

I have two MP3 files that were created from the same source, with different audio within them. Here are the properties from ffprobe
Duration: 00:00:08.86, bitrate: 384 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 24000 Hz, 1 channels, s16, 384 kb/s
NOTE: Even though the file is an MP3 it shows as pcm_s16le
When I try and join the two files together using
ffmpeg -i download.mp3 -i download1.mp3 -filter_complex [0:a:0][1:a:0]concat=n=2:v=0:a=1[outa] -map [outa] joineddownloads.mp3
I get the following result and a big drop in bitrate(quality)
Duration: 00:00:10.42, start: 0.046042, bitrate: 32 kb/s
Stream #0:0: Audio: mp3, 24000 Hz, mono, fltp, 32 kb/s
How can I maintain the high 320kbs bitrate and all the other properties that were present before I created the joined file?
To avoid re-encoding - concatenate the two mp3s
First create a text file ‘files.txt’ containing two lines:
file '/path/download.mp3'
file '/path/download1.mp3'
Second:
ffmpeg -f concat -i files.txt -c copy out.mp3

Extract audio with ffmpeg, linux

I'm trying to extract audio tracks from some Avi videos and save them to their own files, ideally without re-encoding.
I've had a look through here https://www.ffmpeg.org/ffmpeg.html#Audio-Options and here ffmpeg to extract audio from video though I'm getting errors regardless of the approach I try.
My latest command string is:
ffmpeg -i /home/d/Pictures/Test/input-video.AVI -map 0:a -vn -acodec copy /home/d/Pictures/Test/output-audio.m4a
The key part of the output is:
Guessed Channel Layout for Input Stream #0.1 : mono
Input #0, avi, from '/home/d/Pictures/Test/input-video.AVI':
Duration: 00:00:05.94, start: 0.000000, bitrate: 18131 kb/s
Stream #0:0: Video: mjpeg (MJPG / 0x47504A4D), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 17995 kb/s, 30.28 fps, 30.28 tbr, 30.28 tbn, 30.28 tbc
Stream #0:1: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 11025 Hz, 1 channels, s16, 176 kb/s
File '/home/d/Pictures/Test/output-audio.m4a' already exists. Overwrite ? [y/N] y
[ipod # 0x1d89520] Codec for stream 0 does not use global headers but container format requires global headers
[ipod # 0x1d89520] Could not find tag for codec pcm_s16le in stream #0, codec not currently supported in container
Output #0, ipod, to '/home/d/Pictures/Test/output-audio.m4a':
Metadata:
encoder : Lavf56.40.101
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 11025 Hz, mono, 176 kb/s
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
I'm believe I have got the right audio stream number from this output and thus am assuming the "-map 0:a" part isn't the problem.
I'm running on Linux Mint 18.1
MP4 family of formats don't store PCM audio, so you either have to re-encode or save to another format, like Matroska.
ffmpeg -i video.AVI -map 0:a -vn -acodec copy audio.mka

Multichannel AAC mp4 encoding using libav (avconv) or ffmpeg

I am trying to create a four-channel mp4 file with AAC encoding for ambisonics use. I am trying to encode a 4-channel first-order ambisonic wav file into AAC like so:
avconv -i four_channel_input.wav -c:a libfaac -ac 4 four_channel_output.mp4
This gives me the error
[libfaac # 0x7f938885a000] Specified channel_layout is not supported
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Removing the -ac 4 option gives me a 5 channel file
Duration: 00:01:21.09, start: 0.021333, bitrate: 218 kb/s
Stream #0:0(und): Audio: aac (LC) [mp4a / 0x6134706D]
48000 Hz, 5.0, fltp, 215 kb/s (default)
with a blank first channel, which is obviously suboptimal. In order to create compressed ambisonics files, should I be using a separate format like AmbiX (even though I believe this is uncompressed)?
With ffmpeg, you can run
ffmpeg -i input.wav -c:a aac -ac 4 -channel_layout 4.0 four_channel_output.mp4

ffmpeg stdout wrong timecode out

If I run this command line
ffmpeg -ss 0 -t 3600 -i file1.mp3 -ss 0 -t 20 -i file2.mp3 -filter_complex "[0][1]concat=n=2:v=0:a=1" -ac 2 -f wav - > test.wav
I'm basically putting the stout inside a container wav (test.wav) but the duration is always wrong. The output file should be 01:00:20.00 but if I play it on VLC (or any player audio) it shows 06:12:49.00 and even if I change the start_times, the durations and number of files, I still get that timecode out. The even weirder thing is that ffprobe shows the duration as it should be. Can somebody please help me on this?
UPDATE:
[wav # 0000000000cf3680] Ignoring maximum wav data size, file may be invalid
[wav # 0000000000cf3680] Estimating duration from bitrate, this may be inaccurate
Input #0, wav, from 'test.wav':
Metadata:
encoder : Lavf57.72.101
timecode : 01:00:20.00
Duration: 01:00:20.00, bitrate: 1536 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 2 channels, s16, 1536 kb/s
That is what the ffprobe on the output shows..the duration is correct here but not on any audio player

FFmpeg not copying all audio streams

I'm having trouble getting ffmpeg to copy all audio streams from a .mp4 file. After hours of searching online, it appears this should copy all streams (as shown in example 4 here):
ffmpeg -i in.mp4 -map 0 -c copy out.mp4
in.mp4 contains 3 streams:
Video
Audio track 1
Audio track 2
out.mp4 (which should be identical to in.mp4) contains only 2 streams:
Video
Audio track 1
FFmpeg does appear to correctly identify all 3 streams, but doesn't copy all of them over. Output from FFmpeg:
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Stream #0:2 -> #0:2 (copy)
Edit: Output from ffmpeg -v 9 -loglevel 99 -i in.mp4:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from in.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.36.100
Duration: 00:00:06.03, start: 0.000000, bitrate: 5582 kb/s
Stream #0:0(und), 1, 1/15360: Video: h264 (Main), 1 reference frame (avc1 /
0x31637661), yuv420p(tv, bt470bg/unknown/unknown, left), 1920x1080 (0x0) [SAR 1:
1 DAR 16:9], 0/1, 5317 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und), 1, 1/48000: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz,
stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream #0:2(und), 1, 1/48000: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz,
stereo, fltp, 128 kb/s
Metadata:
handler_name : SoundHandler
Successfully opened the file.
At least one output file must be specified
[AVIOContext # 0000000001c2b9e0] Statistics: 153350 bytes read, 2 seeks
Edit 2 (solved): I managed to find the correct syntax from this ticket. For any others that are interested, the correct syntax is:
ffmpeg -i in.mp4 -vcodec copy -c:a copy -map 0 out.mp4
This will copy all streams.
FFmpeg have option to map all streams to output, you have to use option -map 0 to map all streams from input to output.
In full line it might look like:
ffmpeg -i in.mp4 -c copy -map 0 out.mp4
For more info see the documentation on stream selection and the -map option.
Apparently this is a popular question, so I'm posting my solution as an answer (was previously a comment reply) so that others can see.
I managed to find the correct syntax from this ticket. The correct syntax is:
ffmpeg -i in.mp4 -vcodec copy -c:a copy -map 0:0 -map 0:1 -map 0:2 out.mp4
This will copy all 3 streams.
OK, I read pretty deep into the ffmpeg man page and found this which should be useful:
Note that currently each output stream can only contain channels from
a single input stream; you can't for example use "-map_channel" to
pick multiple input audio channels contained in different streams
(from the same or different files) and merge them into a single output
stream. It is therefore not currently possible, for example, to turn
two separate mono streams into a single stereo stream. However
splitting a stereo stream into two single channel mono streams is
possible.
If you need this feature, a possible workaround is to use the amerge
filter. For example, if you need to merge a media (here input.mkv)
with 2 mono audio streams into one single stereo channel audio stream
(and keep the video stream), you can use the following command:
ffmpeg -i input.mkv -filter_complex "[0:1] [0:2] amerge" -c:a pcm_s16le -c:v copy output.mkv
You may want to read through and experiment with the man page instructions on man ffmpeg-filters to understand just what level of complexity you're getting into for naming channels and expected output.
[Edit: As Mulvya noted, this answers a question, but it was not quite the original poster's question.]
First I tried this broader answer here: https://stackoverflow.com/a/54616353/1422630
But I had trouble with a not supported subtitle track so I ended having to use this command:
avconv -i INFILE -c copy -map 0:a -map 0:v OUTFILE
I understand that, after I asked to copy, it basically copied only what I mapped (and it mapped all audio of course), as I don't care for the subtitles being embedded at all. If you want to map the subtitles, just add this -map 0:s.
It seems that specific ffmpeg versions ignore -c copy option and skip audio stream copy, thus resulting in final file with no audio, e.g. does not copy audio tracks and produce video with no sound.
The ffmpeg affected is for example used on Synology Disk Station devices:
ffmpeg version 2.7.7 Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 4.9.3 (crosstool-NG 1.20.0) 20150311 (prerelease)
To resolve that, without analyzing file structure and manually mapping all audio streams with -map 0:1 -map 0:2 etc, I found very simple command to process it automatically:
ffmpeg -i INFILE -map 0 -c copy -c:a copy OUTFILE
This is different from -c:v -c:a as preserves chapters and subtitles together with video and all audio tracks with different languages, like english, spanish, french, russian or chineese.
Also in case you have more hardly broken file, which simple copy does not fix, please try this command, which potentially fix more errors, which could crash video player, or stuck video or audio:
ffmpeg -err_detect ignore_err -i INFILE -map 0 -c copy -c:a copy OUTFILE

Resources