How to combine audio and video in Pytube? - python-3.x

I am trying to write a code to download YouTube videos using Pytube on Python 3.6. But for most videos progressive download(Audio and Video in same file) format is available only upto 360p. So I want to download audio and video files separately and combine it. I am able to to download the audio and video files. How can I combine the two file together?

Basically I don't find any method to marge Audio and Video in Pytube but you can use ffmpeg for muxing.
First of all you have to install ffmpeg
ffmpeg installation guide for Windows
for Ubuntu just sudo apt install ffmpeg
Add a dependency ffmpeg-python a python wrapper of ffmpeg
pip install ffmpeg-python
Now we are ready to go with this code snippet
import ffmpeg
video_stream = ffmpeg.input('Of Monsters and Men - Wild Roses.mp4')
audio_stream = ffmpeg.input('Of Monsters and Men - Wild Roses_audio.mp4')
ffmpeg.output(audio_stream, video_stream, 'out.mp4').run()
for more, ffmpeg-python API References

If you keep getting a video without audio, that's because of the adaptive streaming from pytube. A work-around is to download both video and audio... then merge them with ffpmeg.
For instance, something like this to get both audio and video (audio part adapted from here)
from pytube import YouTube
import os
youtube = YouTube('https://youtu.be/ksu-zTG9HHg')
video = youtube.streams.filter(res="1080p").first().download()
os.rename(video,"video_1080.mp4")
audio = youtube.streams.filter(only_audio=True)
audio[0].download()
and then the ffmpeg part (adapted from both here and here) you can set it up on Windows following this procedure and then run something like
ffmpeg -i video.mp4 -i audio.mp4 -c:v copy -c:a aac output.mp4

Merging audio and video using ffmpeg
Once you have downloaded both video and audio files (‘videoplayback.mp4’ and ‘videoplayback.m4a’ respectively), here’s how you can merge them into a single file:
In case of MP4 format (all, except 1440p 60fps & 2160p 60fps):
ffmpeg -i videoplayback.mp4 -i videoplayback.m4a -c:v copy -c:a copy output.mp4
In case of WebM format (1440p 60fps and 2160p 60fps):
ffmpeg -i videoplayback.webm -i videoplayback.m4a -c:v copy -c:a copy output.mkv
Wait until ffmpeg finishes merging audio and video into a single file named "output.mp4".

How do I convert the downloaded audio file to mp3?
you need to execute the following command in the Command Prompt window:
ffmpeg -i INPUT_FILE -ab BITRATE -vn OUTPUT_FILE
Example:
ffmpeg -i videoplayback.m4a -ab 128000 -vn music.mp3
Example:2 (without bit rate)
ffmpeg -i videoplayback.m4a -vn music.mp3

Related

How to overlay two video files including audio of each video using ffmpeg"

i would like to merge some music (video file) and singing (video file) into one video file.
i've tried with this:
ffmpeg -i music.mp4 -itsoffset 2 -i sing01.mp4 -filter_complex overlay=635:300 test.mp4
and everything is fine, except that i cannot hear the singing. what i should add to this command to do the job correctly?
thanks

Play video file and audio file simultaneously from Linux command line

I would like to play a separate video stream and audio stream simultaneously from the Linux command line, using e.g. cvlc or mpv.
More specifically, I would like to play a youtube video in high quality format, using youtube-dl along with a player.
More details:
I am using this command to playback a youtube video on my pc:
youtube-dl -i <youtube.com/url> -o - | mpv -
Lets say I have following formats for a youtube video available:
249 webm audio only tiny 62k , opus # 50k (48000Hz), 14.14MiB
251 webm audio only tiny 158k , opus #160k (48000Hz), 35.68MiB
303 webm 1920x1080 1080p60 4429k , vp9, 60fps, video only, 536.78MiB
299 mp4 1920x1080 1080p60 6901k , avc1.64002a, 60fps, video only, 884.09MiB
22 mp4 1280x720 720p 1339k , avc1.64001F, 30fps, mp4a.40.2#192k (44100Hz) (best)
youtube-dl would automatically choose the last entry of this list, as it is a format that includes video and audio in one file.
Is there a way I can play the formats 303 and 251 on my pc?
If I would like to download them I would use:
youtube-dl -i <youtube.com/url> -f 303+bestaudio
What youtube-dl does in this case is to download the video and the audio file seperately and merges them into one file using ffmpeg.
But I can't figure if there is a possibility to playback both streams without first downloading them into a file.
Alright I think I figured a solution.
The command I use is as follows:
ffmpeg -loglevel quiet -i $(youtube-dl -g youtube.com/url -f 303) -i $(youtube-dl -g youtube.com/url -f bestaudio) -f matroska -c copy - | mpv -
The youtube-dl -g option would just return the url to the video or audio stream.
In this case it will pass the urls to ffmpeg which is doing the merging process.
-f matroska tells ffmpeg to use the mkv container format
-c copy says that no re-encoding should be done
edit:
For some reason, on my systemm the input is broken after ffmpeg exits. For now I resolve this by typing reset, until I find a better solution to this issue.

No data written to stdin or stderr from ffmpeg

I have a dummy client that is suppose to simulate a video recorder, on this client i want to simulate a video stream; I have gotten so far that i can create a video from bitmap images that i create in code.
The dummy client is a nodejs application running on an Raspberry Pi 3 with the latest version of raspian lite.
In order to use the video I have created, I need to get ffmpeg to dump the video to pipe:1. The problem is that I need the -f rawvideo as a input parameter, else ffmpeg can't understand my video, but when i have that parameter set ffmpeg refuses to write anything to stdio
ffmpeg is running with these parameters
ffmpeg -r 15 -f rawvideo -s 3840x2160 -pixel_format rgba -i pipe:0 -r 15 -vcodec h264 pipe:1
Can anybody help with a solution to my problem?
--Edit
Maybe i sould explain a bit more.
The system i am creating is to be set up in a way, where instead of my stream server ask the video recorder for a video stream, it will be the recorder that tells the server that there is a stream.
I have have slowed my problem on my own. (-:
i now have 2 solutions.
Is to change my -f rawvideo to -f data that works for me anyways.
I can encode my bitmaps as jpeg in code and pipe my jpeg images to stdin. This also requires me to change the ffmpeg parameters to -r 4 -f mjpeg -i pipe:0 -r 4 -vcodec copy -f mjpeg pipe:1 and is by far the slowest thing i have ever done. and i can't use a 4k input
thanks #Mulvya for trying to help.
#eFox Thanks for editing my stupid spelling and grammar mistakes

FFmpeg - What muxer do i need to save an AAC audio stream

I'm developing Android application, and im using ffmpeg for conversion of files.
I want my binary file to be as slim as possible since i don't have many input formats and output formats, and my operation is quite basic.And of course not to bloat the APK.
In my program ffmpeg receives a file, and copys the audio stream (-acodec copy), the audio stream will always be aac (mp4a). What i need is to save the stream to file.
My command looks like this : ffmpeg -i {Input} -vn -acodec copy output.aac.
What muxer do i need to for muxing aac to file? I have tried flv,mp3,mov but i always get
Unable to find a suitable output format for 'output.aac', so these options are wrong.
I don't need an encoder for stream copy btw.
Side note: this command work flawlessly on full installation of ffmpeg , but I don't know which muxer it uses. If there is a way to output the muxer it uses from regular ffmpeg run, it would work too.
A common file format for AAC is BMFF/MOV/MP4/M4A. If you specify the m4a file extension, FFmpeg will take care of it for you.
ffmpeg -i {input} -vn -acodec copy output.m4a
If you just want raw AAC, you can use ADTS as a lightweight container of sorts, as Mulvya suggested.
ffmpeg -i {input} -vn -acodec copy -f adts output.aac
I had to add the -f for me to work (on FFmpeg 3.22):
ffmpeg -i {input} -vn -acodec copy -f adts output.m4a
You have to add adts to --enable-muxer when configuring ffmpeg, eg. ./configure --disable-everything (...) --enable-muxer=adts. Then you will be able to save to .aac file

concatenate video files using ffmpeg - garbled images but audio okay

I am trying to concatenate video files so that next one follows the one before it when it is played. The formatting for all of the files are the same. The files all have audio & video.
I think I am very close (hopefully!) to getting this to work, but I have one final problem. The command below takes all of the mp4 files in my folder and creates a big mp4 file, which is the right size in total MB, but the images for all videos after the first video are garbled. The audio is okay (continues just fine from video to video). Also, I don't get any error messages.
ffmpeg -f concat -i <(for f in /folder1/*.mp4; do echo "file '$f'"; done) -c copy /folder1/all.mp4
I'm not very familiar with ffmpeg yet, so I've just been trying the different suggestions I've found on the web. Can anyone suggest other things for me to try? (I've tried reading the FAQs, but I have to confess that I don't fully understand it. Also, there seems to be some posts about audio being missing after concatenation, but I haven't seen anything on images being garbled.) Thx in advance!
I have had good luck using this ... avconv is a fork of ffmpeg
avconv -i 1.mp4 1.mpeg
avconv -i 2.mp4 2.mpeg
avconv -i 3.mp4 3.mpeg
cat 1.mpeg 2.mpeg 3.mpeg | avconv -f mpeg -i - -vcodec mpeg4 -strict experimental output.mp4

Resources