Ошибка FFMpeg при преобразовании из MP4 в MP3 в Python

Когда я пытаюсь конвертировать видео из плейлиста YouTube, я получаю сообщение об ошибке: "Файл "C:\Users\fonti\AppData\Local\Programs\Python\Python310\lib\site-packages\ffmpy.py", строка 106, выполняется поднять FFRuntimeError(self.cmd, self.process.returncode, out[0], out[1]) ffmpy.FFRuntimeError: C:/ffmpeg/bin/ffmpeg.exe -i "Nightcore - To Be Human // lyrics.mp4" "Nightcore - To Be Human // lyrics.mp3" завершен со статусом 1"

Код, который я использую:

from pytube import Playlist
import ffmpy
from ffmpy import FFmpeg

playlistLink = input("Introduz o link da Playlist: ")
playlist = Playlist(playlistLink)   

diretório = 'E'
while diretório != 'M' and diretório != 'V':
    diretório = input("Vais baixar música ou vídeos? (M/V)")
    if diretório == 'M':
        downloadDirectory = "C:/Users/fonti/Documents/Projetos Python/Youtube/Músicas"
    elif diretório == 'V':
        downloadDirectory = "C:/Users/fonti/Documents/Projetos Python/Youtube/Vídeos"

print("Número total de vídeos a baixar: ", len(playlist.video_urls))    

print("\n\n Links dos vídeos:\n")

for url in playlist.video_urls:
    print(url) 

def MP3():
    for video in playlist.videos:

        audio = video.streams.get_audio_only()
    
        audio.download(downloadDirectory)

        videoTitle = video.title
    
        new_filename = videoTitle + '.mp3'
        default_filename = videoTitle + '.mp4'
    
        print(default_filename+'\n\n'+new_filename)

        ff = ffmpy.FFmpeg(
            executable = 'C:/ffmpeg/bin/ffmpeg.exe',
            inputs = {default_filename : None},
            outputs = {new_filename : None}
        )
        ff.run()


def MP4():
    for video in playlist.videos:
        print('Downloading : {} with url : {}'.format(video.title, video.watch_url))
        video.streams.\
            filter(type='video', progressive=True, file_extension='mp4').\
            order_by('resolution').\
            desc().\
            first().\
            download(downloadDirectory)

escolha = 'E'
while escolha != 'V' and escolha != 'A':
    escolha = input("Queres formato de vídeo ou áudio (V/A)? ")
    if escolha == 'V':
        MP4()
    elif escolha == 'A':
        MP3()
    else:
        print("Escolha inválida")

Если я пытаюсь загрузить видео из плейлиста, все работает нормально. Но когда я пытаюсь скачать аудио, выдает ошибку.

Обычно есть некоторый вывод от ffmpeg, объясняющий, почему он вышел. Код ошибки 1 не очень специфичен и может соответствовать множеству разных вещей. Можете ли вы проверить вывод из ffmpeg?

Nick ODell 04.11.2022 20:31
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
92
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мы можем использовать полный путь, чтобы FFmpeg мог найти файлы. Мы можем объединить downloadDirectory с videoTitle для создания полного пути:

def MP3():
        ...
        videoTitle = video.title

        videoTitle = os.path.join(downloadDirectory, videoTitle)

        new_filename = videoTitle + '.mp3'
        ...

Полный пример кода:

from pytube import Playlist
import ffmpy
from ffmpy import FFmpeg
import os

playlistLink = 'https://www.youtube.com/playlist?list=PLS1QulWo1RIaJECMeUT4LFwJ-ghgoSH6n' #input("Introduz o link da Playlist: ")
playlist = Playlist(playlistLink)   

diretório = 'E'
while diretório != 'M' and diretório != 'V':
    diretório = 'M' #input("Vais baixar música ou vídeos? (M/V)")
    if diretório == 'M':
        downloadDirectory = "C:/Users/fonti/Documents/Projetos Python/Youtube/Músicas"
    elif diretório == 'V':
        downloadDirectory = "C:/Users/fonti/Documents/Projetos Python/Youtube/Vídeos"

print("Número total de vídeos a baixar: ", len(playlist.video_urls))    

print("\n\n Links dos vídeos:\n")

for url in playlist.video_urls:
    print(url) 

def MP3():
    for video in playlist.videos:

        audio = video.streams.get_audio_only()
    
        audio.download(downloadDirectory)

        videoTitle = video.title

        videoTitle = os.path.join(downloadDirectory, videoTitle)  # Concatenate the directory and the file name
    
        new_filename = videoTitle + '.mp3'
        default_filename = videoTitle + '.mp4'        
    
        print(default_filename+'\n\n'+new_filename)

        ff = ffmpy.FFmpeg(
            executable = 'C:/ffmpeg/bin/ffmpeg.exe',
            inputs = {default_filename : None},
            outputs = {new_filename : None}
        )
        ff.run()


def MP4():
    for video in playlist.videos:
        print('Downloading : {} with url : {}'.format(video.title, video.watch_url))
        video.streams.\
            filter(type='video', progressive=True, file_extension='mp4').\
            order_by('resolution').\
            desc().\
            first().\
            download(downloadDirectory)

escolha = 'E'
while escolha != 'V' and escolha != 'A':
    escolha = 'A' #input("Queres formato de vídeo ou áudio (V/A)? ")
    if escolha == 'V':
        MP4()
    elif escolha == 'A':
        MP3()
    else:
        print("Escolha inválida")

Более надежное решение — поиск файла .mp4 в папке и удаление его после преобразования в mp3:

from pytube import Playlist
import ffmpy
from ffmpy import FFmpeg
import os
import glob

playlistLink = 'https://www.youtube.com/playlist?list=PLS1QulWo1RIaJECMeUT4LFwJ-ghgoSH6n' #input("Introduz o link da Playlist: ")
playlist = Playlist(playlistLink)   

diretório = 'E'
while diretório != 'M' and diretório != 'V':
    diretório = 'M' #input("Vais baixar música ou vídeos? (M/V)")
    if diretório == 'M':
        downloadDirectory = "C:/Users/fonti/Documents/Projetos Python/Youtube/Músicas"
    elif diretório == 'V':
        downloadDirectory = "C:/Users/fonti/Documents/Projetos Python/Youtube/Vídeos"

print("Número total de vídeos a baixar: ", len(playlist.video_urls))    

print("\n\n Links dos vídeos:\n")

for url in playlist.video_urls:
    print(url) 

def MP3():
    # Delete all mp4 files in Músicas folder
    mp4_files = glob.glob(os.path.join(downloadDirectory, '*.mp4'))  # dir C:/Users/fonti/Documents/Projetos Python/Youtube/Músicas/*.mp4
    for f in mp4_files:
        os.remove(f)

    for video in playlist.videos:

        audio = video.streams.get_audio_only()
    
        audio.download(downloadDirectory)

        videoTitle = video.title
        videoTitle = videoTitle.strip() # use the strip() method to remove trailing and leading spaces https://stackoverflow.com/a/10443548/4926757
       
        # List all mp4 files in the directory.
        videoTitle = glob.glob(os.path.join(downloadDirectory, '*.mp4'))  # dir C:/Users/fonti/Documents/Projetos Python/Youtube/Músicas/*.mp4
        
        #videoTitle = os.path.join(downloadDirectory, videoTitle)  # Concatenate the directory and the file name
    
        #new_filename = videoTitle + '.mp3'
        #default_filename = videoTitle + '.mp4'

        default_filename = videoTitle[0]  # Suppused to be only one mp4 file in the folder.
        new_filename = default_filename.replace('.mp4', '.mp3')  # Remplace .mp4 with .mp3
    
        print(default_filename+'\n\n'+new_filename)

        ff = ffmpy.FFmpeg(
            executable = 'C:/ffmpeg/bin/ffmpeg.exe',
            inputs = {default_filename : None},
            outputs = {new_filename : None}
        )
        ff.run()

        os.remove(default_filename)  # Delete the mp4 file


def MP4():
    for video in playlist.videos:
        print('Downloading : {} with url : {}'.format(video.title, video.watch_url))
        video.streams.\
            filter(type='video', progressive=True, file_extension='mp4').\
            order_by('resolution').\
            desc().\
            first().\
            download(downloadDirectory)

escolha = 'E'
while escolha != 'V' and escolha != 'A':
    escolha = 'A' #input("Queres formato de vídeo ou áudio (V/A)? ")
    if escolha == 'V':
        MP4()
    elif escolha == 'A':
        MP3()
    else:
        print("Escolha inválida")

Спасибо за помощь. Кроме того, что делает glob.glob(os.path.join(downloadDirectory, '*.mp4'))?

Jack142 05.11.2022 13:28

Это как dir C:\SomePath\*.mp4 — возвращает список всех .mp4 файлов в downloadDirectory папке. Мы могли бы применить glob.glob(downloadDirectory + '/*.mp4'), но использование os.path.join более надежно (работает, если строка каталога заканчивается на \).

Rotem 05.11.2022 22:08

Другие вопросы по теме