ffmpeg: How to assign an empty soundtrack to a video? - audio

I'm using ffmpeg to build a short hunk of video from a machine-generated png. This is working, but the video now needs to have a soundtrack (an [audio] field) for some of the other things I'm doing with it. I don't actually want any sound in the video, so: is there a way to get ffmpeg to simply set up an empty soundtrack property in the video, perhaps as part of the call that creates the video? I guess I could make an n-second long silent mp3 and bash it in, but is there a simpler / more direct way? Thanks!

Thanks to #Alvaro for the links; one of these worked after a bit of massaging. It does seem to be a two-step process: First make the soundtrack-less video and then do:
ffmpeg -ar 44100 -acodec pcm_s16le -f s16le -ac 2 -channel_layout 2.1
-i /dev/zero -i in.mp4 -vcodec copy -acodec libfaac -shortest out.mp4
The silence comes from /dev/zero and -shortest makes the process stop at the end of the video. Argument order is significant here; -shortest needs to be down near the output file spec.
This assumes that your ffmpeg installation has libfaac installed, which it might not. But, otherwise, this seems to be working.

I guess you need to create a media file properly with audio and video stream. As far as i know, there is not a direct way.
If you know your video duration, first create the dummy audio and after when you create the video try to join the audio part.
In superuser, you can find more info link1 link2

Related

Can ffmpeg transcode an audio track and add it as a second audio track at the same time, or if not, how to do it as separate commands?

A bit of history. I am using Plex as my media server, but for reasons unknown, it has issues transcoding the DTS-HD MA 7.1 audio to EAC3 stereo and keeps buffering (the server has plenty of horsepower on all fronts, CPU/RAM/drive space & speed, gigabit networks connections for all devices. The playback device (TCL Roku TV, with a 3rd party soundbar connected via HDMI ARC) doesn't support the built-in 7.1 audio, so I get silence if I play it back directly by putting the file on a USB stick.
Also, I am by no means a ffmpeg guru, I figured out what I do know by Google University and asking questions, so please be kind and forgive me if I ask follow-up questions that may seem n00b-ish, and please provide example commands (preferably in the context of my command below so that I can have a known point of reference to start with).
I have a movie with 4K (HEVC Main 10 HDR) video and DTS-HD MA 7.1 audio that I am looking to leave the video and audio untouched, but to add a 2nd audio track in either EAC3 or if necessary, just AC3 in stereo
So what I am looking for is as follows:
video.mkv
Existing->4k video file (no change)
Existing->7.1 audio (no change)
Convert and add->stereo audio as a 2nd audio track to the output.mkv file
Below is the command I've historically used with ffmpeg to convert and replace the audio file with the stereo audio, but since I'd prefer to leave the 7.1 audio in place, this doesn't work:
ffmpeg -i "D:\video.mkv" -c:v copy -c:a aac -b:a 128k "D:\output.mkv"
And if this cannot be done as a single command, please also let me know what steps I do need to take to be able to do it.
Thanks in advace,
Mike
ffmpeg -i input.mkv -map 0 -map 0:a -c copy -c:a:1 eac3 output.mkv
-map 0 select all streams.
-map 0:a select all audio streams. This combines with -map 0 so now you have 1 video and 2 audio streams selected.
-c copy stream copy all streams.
-c:a:1 eac3 encode output audio stream #1 with eac3 encoder. This overrides -c copy for this particular stream.

Use ffmpeg to sequentially add multiple audio tracks and pin a specific track to the end

I have a single video with no audio tracks and want to add several audio tracks sequentially (each track starts immediately after the other).
The basic case might look something like this:
|-----------VIDEO-----------VIDEO-------------VIDEO-----------VIDEO-----------|
|---FULL AUDIO TRACK 1---|---FULL AUDIO TRACK 2---|---PARTIAL AUDIO TRACK 3---|
Here is my attempt to achieve this:
ffmpeg -i video.mov -i audio1.mp3 -i audio2.mp3 -i audio3.mp3 -map 0:0 -map 1:0 -map 2:0 -map 3:0 out.mp4
Of course it doesn't produced the desired result. It only uses the first music clip in out.mp4, and no other audio tracks are started when it ends.
Question 1
What am I missing in order to add multiple audio tracks sequentially? I assume it's specifying starting and end points of audio clips but I'm coming up short on locating the syntax.
...
In addition, I'm looking for a way to ensure that the video ends with the full duration of AUDIO TRACK 3, as seen below:
|-----------VIDEO-----------VIDEO-------------VIDEO-----------VIDEO-----------|
|---FULL AUDIO TRACK 1---|---PARTIAL AUDIO TRACK 2---|---FULL AUDIO TRACK 3---|
In this case, AUDIO TRACK 2 gets trimmed so that the full AUDIO TRACK 3 is pinned to the end.
Question 2
Can this type of audio pinning be done in FFmpeg, or would I have to trim AUDIO TRACK 2 with another program first?
Use the atrim, asetpts, and concat filters:
ffmpeg -i video.mov -i audio1.mp3 -i audio2.mp3 -i audio3.mp3
-filter_complex "[2:a]atrim=duration=5,asetpts=PTS-STARTPTS[a2];[1:a][a2][3:a]concat=n=3:a=1:v=0[a]"
-map 0:v -map "[a]" -c copy -c:a aac -shortest output.mp4
atrim trims the audio. You can also use the start and/or end options if you prefer them over duration.
asetpts resets the timestamps (required by concat).
concat concatenates each audio segment.
If you want to automate this you'll have to script it. You can get the duration of each input with ffprobe:
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4
Then use that to determine the duration of whatever audio stream you want to trim.

ffmpeg conversion to mp4 shifts the audio by one frame

I have a .mov file (codec = motion jpeg) that has an audio stream that includes small pulses at every second.
When I convert this file to mp4 using ffmpeg I notice that all my pulses are now off by one frame.
I simply used "ffmpeg -i source_file.mov target_file.mp4"
Here is an image of the comparison between the audio signals:
A1 is the original audio (.mov) and A2 is the mp4 output audio of ffmpeg.
As you can see the pulses are one frame late compared to the original.
I know that the h264 codec is lossy but one frame offset seems like a big loss if you ask me.
Is there any option I could use with ffmpeg to have a better audio stream ?
Here is the input file: https://www.dropbox.com/s/6y5g7lo5dvu0ub1/BBB_09_tree_trunk_009_ANIM_001.mov?dl=0
Here is the output file:
https://www.dropbox.com/s/10zuzwn0qs8l853/BBB_09_tree_trunk_009_ANIM_001.mp4?dl=0
If you copy the audio over, you shouldn't get the shift.
ffmpeg -i source_file.mov -c:a copy target_file.mp4
I've been working on this issue for my own needs and my file format has to be mp4. I'm working from mxf files. I've tried several options and found this to give the most accurate result (I've removed specifics for simplicity):
ffmpeg -ss 00:00:00.021 -i "input.mxf" -itsoffset -0.044 -i "input.mxf" -c:v libx264 -c:a aac -map 0:a -map 1:v "output.mp4"
Starting the first file at 21ms and mapping it as the audio, then shifting the video back 44ms gave gave me the most accurate sync (within several samples). I don't know why 22ms wasn't as accurate (when that's what the primer sample issue seems to equate to) and I found nothing that allowed me to work more granular, in samples. A filter with a PTS offset had no affect. Perhaps it works differently with different file formats. It's also worth noting that the same command without the -itsoffest gave the same sync result with one difference; the video stream duration was 1 frame and 1ms off the audio and container durations. With the -itsoffest, the durations were only 1ms different. You can use 22ms to achieve an accurate duration, but check your sync, it might be out that slightest bit more.
Also worth noting that I stumbled across some developer commentary on the -itsoffset tag which clarified that it doesn't work on audio, it works on video. It seems like the answer above is suggesting to map the offest against the audio, which apparently is not how the function is built to work. https://trac.ffmpeg.org/ticket/1349
try mpeg2 audio: -acodec mp2 it worked for me

ffmpeg convert mp4 video for phones

I need to make a video which will play on iPhone and Android but the problem is when I click play on the phone it needs minimum 7 seconds to start.
So maybe I need to fix something in this code to make the video play on phones (maybe another format is needed):
ffmpeg -i VIDEO -c:v libx264 -s 640x480 -strict experimental -c:a aac VIDEO.MP4
There must be something to make the video play faster without a delay on start.
I tried a FLV file and it worked fine on Android but the iPhone can't play it.
If you're referring to a progressive download scenario then you can use:
-movflags faststart
Run a second pass moving the index (moov atom) to the beginning of the
file. This operation can take a while, and will not work in various
situations such as fragmented output, thus it is not enabled by
default.
Source
The moov atom is generally at the end of the file and a full download is required before playback in this case. Moving it to the start with the aforementioned command allows the playback to start immediately.

Download ONLY audio from a youtube video

I know that there are a million ways to download a video from youtube and then convert it to audio or do further processing on it. But recently I was surprised to see an app called YoutubeToMp3 on mac actually showing "Skipping X mb of video" and supposedly only downloading the audio from the video, without the need to use bandwith to download the entire video and then convert it. I was wondering if this is actually correct and possible at all because I cant find any way to do that. Do you have any ideas ?
EDIT:
After some tests here is some additional information on the topic. The video which I tried to get the audio from is just a sample mp4 file from the internet:
http://download.wavetlan.com/SVV/Media/HTTP/MP4/ConvertedFiles/MediaCoder/MediaCoder_test6_1m9s_XVID_VBR_306kbps_320x240_25fps_MPEG1Layer3_CBR_320kbps_Stereo_44100Hz.mp4
I tried
ffmpeg -i "input" out.mp3
ffmpeg -i "input" -vn out.mp3
ffmpeg -i “input” -vn -ac 2 -ar 44100 -ab 320k -f mp3 output.mp3
ffmpeg -i “input” -vn -acodec copy output.mp3
Unfortunately non of these commands seems to be using less bandwith. They all download the entire video. Now that you have the video can you confirm if there is actually a command that downloads only the audio stream from it and lowers the bandwith usage? Thanks!
After a lot of research I found out that this is not possible and developed an alternative approach:
Download the mp4 header
Parse the header and get the locations of the audio bytes
Download the audio bytes with http range requests and offsets
Assemble the audio bytes and wrap them in a simple ADTS container to produce a playing m4a file
That way only bandwidth for the audio bytes is used. If you find a better approach of doing it please let me know.
For a sample Android APP and implementation check out:
https://github.com/feribg/audiogetter/blob/master/audiogetter/src/main/java/com/github/feribg/audiogetter/tasks/download/VideoTask.java
FFmpeg is capable of accepting an URL as input. If the URL is seekable, then FFmpeg could theoretically skip all the video frames, and thus it would need to download only the data for the audio stream.
Try using
ffmpeg -i http://myvideo.avi out.mp3
and see if it takes less bandwidth.

Resources