Creating Youtube audio downloader

Hello, i am trying to build a streamlit app to download “audio” youtube videos, using the library Pytube.

The purpose is to allow downloading audio files even after hosting the app (not only in local).

Here is the code i am using :

def download_audio(url):
    global title_vid

    youtube_video = YouTube(url)
    title_vid=youtube_video.title

    with tempfile.NamedTemporaryFile(delete=True) as temp:
        file_path = temp.name + ".mp3"
        audio = youtube_video.streams.get_audio_only()
        audio.download(file_path)
        temp.close()

    return file_path

def main():
    url = st.text_input("Insert URL:")
    if url:
        data_file_path = download_audio(url)
        
        with open(data_file_path, "rb") as f:
            data_b = f.read()

        st.download_button(
            label="Download",
            data=data_b,
            file_name=f"{title_vid}.mp3",
            mime="audio/mpeg")

main()

When i try to use this i get this error :

with open(data_file_path, “rb”) as f:
PermissionError: [Errno 13] Permission denied : ‘file_path’

Can anyone help me handling this issue

I wouldn’t use any temporary files at all.
I would use io.BytesIO buffer instead.
This example should work:

from io import BytesIO
from pathlib import Path

import streamlit as st
from pytube import YouTube

st.set_page_config(page_title="Download Audio", page_icon="🎵", layout="centered", initial_sidebar_state="collapsed")

@st.cache_data(show_spinner=False)
def download_audio_to_buffer(url):
    buffer = BytesIO()
    youtube_video = YouTube(url)
    audio = youtube_video.streams.get_audio_only()
    default_filename = audio.default_filename
    audio.stream_to_buffer(buffer)
    return default_filename, buffer

def main():
    st.title("Download Audio from Youtube")
    url = st.text_input("Insert Youtube URL:")
    if url:
        with st.spinner("Downloading Audio Stream from Youtube..."):
            default_filename, buffer = download_audio_to_buffer(url)
        st.subheader("Title")
        st.write(default_filename)
        title_vid = Path(default_filename).with_suffix(".mp3").name
        st.subheader("Listen to Audio")
        st.audio(buffer, format='audio/mpeg')
        st.subheader("Download Audio File")
        st.download_button(
            label="Download mp3",
            data=buffer,
            file_name=title_vid,
            mime="audio/mpeg")

if __name__ == "__main__":
    main()
2 Likes

Hello, i just want to thank you for this great help.
I learned a lot from this code and the logic behind !

Is it possible to give me an example about downloading youtube videos ?
I tried to keep the same logic as your audio example, but i still have some issues.
Here is the code :

import streamlit as st
from pytube import YouTube
from io import BytesIO
from pathlib import Path

st.set_page_config(page_title="Download Video", page_icon="🎵", layout="centered", initial_sidebar_state="collapsed")

@st.cache_data(show_spinner=False)
def download_video_to_buffer(url):
    buffer = BytesIO()
    youtube_video = YouTube(url)
    video = youtube_video.streams.filter(progressive="True",file_extension="mp4").order_by('resolution').desc()
    video_720p=video[0]
    default_filename = video_720p.default_filename
    video_720p.stream_to_buffer(buffer)
    return default_filename, buffer

def main():
    st.title("Download video from Youtube")
    url = st.text_input("Insert Youtube URL:")
    if url:
        with st.spinner("Downloading video Stream from Youtube..."):
            default_filename, buffer = download_video_to_buffer(url)
        st.subheader("Title")
        st.write(default_filename)
        title_vid = Path(default_filename).with_suffix(".mp4").name
        st.subheader("Watch the video")
        st.video(buffer, format='video/mpeg')
        st.subheader("Download Audio File")
        st.download_button(
            label="Download mp4",
            data=buffer,
            file_name=title_vid,
            mime="video/mpeg")

if __name__ == "__main__":
    main()

Have a great day !

What kind of issues? Error messages?

OH my Apologizes, i was running the code with this line :

video = youtube_video.streams.filter(progressive="True",file_extension="mp4").order_by('resolution').desc().first()

Which is incorrect. (we have to remove the : “.first()”)

Any way, thank you for your help !

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.