How can I send audio to FFMPEG with Vapoursynth? - audio

Vapoursynth officially added audio support in September, and had it in testing before then. Since it now supports audio, I'm looking to convert over some old Avisynth projects to Vapoursynth. Part of this is driven by my familiarity with Python, and part of it is that it's far easier to set up Vapoursynth with QTGMC in my linux distro of choice.
Anyway, my problem is that when I run the script and pipe the result over to FFMPEG, FFMPEG only gets the video stream and not the audio stream. From a script standpoint, it looks like I should be doing everything right, but there is so little documentation on working with audio that I can't be sure. I'm leaning toward an issue with my vspipe command, but I'm not sure what needs to be done to say "There is audio in this stream"
Here is the script followed by the vspipe/ffmpeg command:
import vapoursynth as vs
import havsfunc as haf
import math
core = vs.core
# Assume NTSC standard framerate and 48kHz as default
def framesToSamples(frameNum, framerate=29.97, samplerate=48000):
return math.floor((samplerate/framerate)*frameNum)
video = core.ffms2.Source(r'Home Movies 1 - 1989.avi', format=vs.YUV422P8)
audio = core.bas.Source(r'Home Movies 1 - 1989.avi', track=1)
video = video[71:217640]
audio = audio[framesToSamples(71):framesToSamples(217640)]
video = core.cnr2.Cnr2(video,"ooo",8,16,191,100,255,32,255,False) #VHS
video = haf.QTGMC(video, Preset="Very Slow", EZDenoise=2.0, TrueMotion=True, ChromaMotion=True, TFF=False)
video = core.std.Crop(video,4,0,4,6)
video = core.resize.Lanczos(video, 352, 240, format=vs.YUV422P10)
video.set_output(0)
audio.set_output(1)
And the command to convert:
vspipe -c y4m "Home Movies 1 - 1989.vpy" - | ffmpeg -i pipe: -c:v libx265 -preset fast -crf 24 -c:a libopus -b:a 96k -ac 1 Test.mkv

From what I have been able to find, vspipe can select one output stream, but it can't output both at the same time. The result is that you end up having to do something like this:
vspipe -o 1 -c wav "Home Movies 1 - 1989.vpy" - | ffmpeg -i pipe: -c:a libopus -b:a 96k -ac 1 audio.opus
vspipe -o 0 -c y4m "Home Movies 1 - 1989.vpy" - | ffmpeg -i pipe: -i audio.opus -c:v libx265 -preset ultrafast -crf 24 -c:a copy "Home Movies 1 - 1989.mkv"
rm audio.opus
The first run produces the audio and places it into a temporary file. Then the second run processes the video and copies the audio into the final video file. Once that's done, the temporary audio file can be deleted.

Related

FFmpeg stream dynamic png

I would like to know if its possible to stream a png or any kind of image using ffmpeg. I would like to generate the image contiously using nodejs that updates every 10 seconds. I would like to display game stats with this in a corner and mix it with some background music or pre recorded commentary on it. Additionaly i would like to mix a video and the image should act like an overlay.
I am also not sure if using a transparent png image its possible to do
I couldn't get my head around doing the mixing with ffmpeg and its looks very complicated so i would like to get some help on it.
I have video files stored in a folder that i would like to continously stream and mix different music and an image on it. I would like to have it all continously working without stopping the stream.
Is it possible with ffmpeg cli on linux or i cant avoid using a desktop windows pc for such thing?
Well after digging through the documentation and asking for help on irc i came up with the following command:
First i store the list of tracks in a txt file such as:
playlist.txt
file 'song1.mp3'
file 'song2.mp3'
file 'song3.mp3'
Then i want to concat the tracks so i use -concat and specify the input as a txt file.
The second thing is using a static image as an input that i can manually update.
ffmpeg -re -y -f concat -safe 0 -i playlist.txt -framerate 1 -loop 1 -f image2 \
-vcodec libx264 -pix_fmt yuv420p -preset ultrafast -r 12 -g 24 -b:v 4500k \
-acodec libmp3lame -ar 44100 -threads 6 -qscale 3 -b:a 128k -bufsize 512k \
-f flv "rtmp://"
The rest is specificing the output format and other settings for streaming.
Thats what i came up with so far, not sure if theres any better way of doing this but right now it is sufficient enough for my needs.

FFMPEG encode audio and forced subtitles at same time?

I'm using latest static build of ffmpeg windows.
My input file (.mkv) is:
[video] - 1080, V_MPEG4/ISO/AVC, 14.6 Mbps, ID#0
[audio] - DTS 5.1, 1510 Kbps, ID#1
[subtitles] - S_TEXT/ASS Lossless English, ID#14
My problem is this: I convert the audio, so that my target player, a XB1 console (media support faq), is able to play audio/video. However sometimes its rather difficult to hear or parts may be in foreign language, so I want to force the english subtitles into the mix at the same time I convert the audio.
Currently for the audio, I use the following command
ffmpeg -i input.mkv -codec copy -acodec ac3 output.mkv
Can I somehow tie in the forced subtitles (onto the video) in order to save an extra process of taking the output.mkv and trying to force subtitles on?
Edit: I've tried using the following command to extract subtitles to be able to edit them
ffmpeg -i Movie.mkv -map 0:s:14 subs.srt
However i get the error: Stream map '0:s:14' matches no streams
Edit2: attempted to extract subtitles and succeeded with
ffmpeg -i input.mkv -map 0:14 -c copy subtitles.ass
but still looking to force the subtitles, nonetheless!
Also - a little bonus to this question - can I somehow extract the .ass file and edit it to only produce subtitles for foreign parts - so english audio doesn't have subtitles during the movie but foreign audio does have subtitles?
Cheers
Edit3:
When I try to use both of the commands at once (my earlier mentioned audio converter & one from the ffmpeg wiki)
ffmpeg -i input.mkv -codec copy -acodec ac3 -vf "ass=subs.ass" output.mkv
I get the following error from ffmpeg,
Filtergraph 'ass=subs.ass' was defined for video output stream 0:0 but codec copy was selected.
Filtering and streamcopy cannot be used together.
Since your media player does not support subtitles, the text has to be burnt onto the video image. For that, use
ffmpeg -i input.mkv -vf "ass=subs.ass" -c:v libx264 -crf 20 -c:a ac3 output.mkv
This will re-encode the video, since text is being added. The CRF value controls the video quality. Lower values produce better quality but larger files. 18 to 28 is a decent range to try.

FFMPEG merging audio and video to get resulting video

I need to merge audio and video using ffmpeg so that, it should result in a video with the same duration as of audio.
I have tried 2 commands for that requirement in my linux terminal. Both the commands work for a few of the input videos; but for some other input_videos, they produce output same as the input video, the audio doesn't get merged.
The commands, I have tried are -
ffmpeg -i wonders.mp4 -i Carefull.mp3 -c copy testvid.mp4
and
ffmpeg -i wonders.mp4 -i Carefull.mp3 -strict -2 testvid.mp4
and
ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict
experimental output.mp4
and these are my input videos -
samplevid.mp4
https://vid.me/z44E
duration - 28 seconds
size - 1.1 MB
status - working
And
wonders.mp4
https://vid.me/gyyB
duration - 97 seconds
size - 96 MB
status - not working
I have observed that the large size (more than 2MB) of the input video is probably the issue.
But, still I want the fix.

Problems with point to point streaming using FFmpeg

I want to live stream video from webcam and sound from microphone from one computer to another but there is some problems.
When I use this command line:
ffmpeg.exe -f dshow -rtbufsize 500M -i video="Camera":audio="Microphone" -c:v mpeg4 -c:a mp2 -f mpegts udp://127.0.0.1:1234
FFmpeg console starts filling with yellow color messages and stream becomes unstable: http://s16.postimg.org/qglcgr345/Untitled.png
To solve this problem I have added new parameter to the command line to set the frame rate -r 25:
ffmpeg.exe -f dshow -rtbufsize 500M -r 25 -i video="Camera":audio="Microphone" -c:v mpeg4 -c:a mp2 -f mpegts udp://127.0.0.1:1234
After I added -r 25 problem with yellow color messages disappears but then appears another problem. When I fresh start FFmpeg with this command line video and sound looks synchronous but after one or two minutes appears ~25 seconds lag between video and sound, sound goes behind video. I have tried that with different protocols UDP, TCP, RTP but problems are the same. Please help me!
I found answer for my problem with "-r" and asynchronous audio and video. Who is interested answer is here: https://trac.ffmpeg.org/wiki/DirectShow (in paragraph "Specifying input framerate").

Normalize audio in an avi file

I have an avi file that has different levels of audio. Is there a way to decrease and increase appropriately where needed the audio of my file using ffmpeg?
In ffmpeg you can use the volume filter to change the volume of a track. Make sure you download a recent version of the program.
Find out the gain to apply
First you need to analyze the audio stream for the maximum volume to see if normalizing would even pay off:
ffmpeg -i video.avi -af "volumedetect" -f null /dev/null
Replace /dev/null with NUL on Windows. This will output something like the following:
[Parsed_volumedetect_0 # 0x7f8ba1c121a0] mean_volume: -16.0 dB
[Parsed_volumedetect_0 # 0x7f8ba1c121a0] max_volume: -5.0 dB
[Parsed_volumedetect_0 # 0x7f8ba1c121a0] histogram_0db: 87861
As you can see, our maximum volume is -5.0 dB, so we can apply 5 dB gain. If you get a value of 0 dB, then you don't need to normalize the audio.
Apply the volume filter:
Now we apply the volume filter to an audio file. Note that applying the filter means we will have to re-encode the audio stream. What codec you want for audio depends on the original format, of course. Here are some examples:
Plain audio file: Just encode the file with whatever encoder you need:
ffmpeg -i input.wav -af "volume=5dB" output.mp3
Your options are very broad, of course.
AVI format: Usually there's MP3 audio with video that comes in an AVI container:
ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi
Here we chose quality level 2. Values range from 0–9 and lower means better. Check the MP3 VBR guide for more info on setting the quality. You can also set a fixed bitrate with -b:a 192k, for example.
MP4 format: With an MP4 container, you will typically find AAC audio. We can use ffmpeg's build-in AAC encoder.
ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -strict experimental -b:a 192k output.mp4
Here you can also use other AAC encoders. Some of them support VBR, too. See this answer and the AAC encoding guide for some tips.
In the above examples, the video stream will be copied over using -c:v copy. If there are subtitles in your input file, or multiple video streams, use the option -map 0 before the output filename.
The author's info is: Jon Skarpeteig in SuperUser
You can use my ffmpeg-normalize script for that.
First, install a recent version of ffmpeg. Then, install via pip install ffmpeg_normalize, then run it on an AVI file:
ffmpeg-normalize input.avi -o output.mkv -c:a aac -b:a 192k
Here, we're choosing to re-encode the audio with AAC at 192 kBit/s, and copy the video stream over to the output. This will perform EBU R128 normalization, but simple peak/RMS normalization is also possible.

Resources