web-dev-qa-db-fra.com

Comment télécharger une partie de la vidéo avec la commande youtube-dl?

J'utilise Ubuntu et la commande youtube-dl Fonctionne parfaitement.

Cependant, maintenant je veux télécharger seulement une partie d'une vidéo trop longue. Je veux donc télécharger seulement quelques minutes de cette vidéo, par exemple de la minute 13 à la minute 17.

Y'a-t'il un quelconque moyen d'y arriver?

87
user3181614

Je ne crois pas youtube-dl seul fera ce que vous voulez. Cependant, vous pouvez le combiner avec un utilitaire de ligne de commande comme ffmpeg.

Acquérir d'abord l'URL réelle en utilisant youtube-dl:

youtube-dl -g "https://www.youtube.com/watch?v=V_f2QkBdbRI"

Copiez la sortie de la commande et collez-la dans le cadre du -i paramètre de la commande suivante:

ffmpeg -ss 00:00:15.00 -i "OUTPUT-OF-FIRST URL" -t 00:00:10.00 -c copy out.mp4

Le -ss Le paramètre dans cette position indique de supprimer toutes les entrées jusqu'à 15 secondes dans la vidéo. Le -t indique les états à capturer pendant 10 secondes. Le reste de la commande lui indique de stocker en tant que mp4.

ffmpeg est un outil populaire et devrait figurer dans l'un des référentiels OS/gestionnaires de packages les plus populaires.

67
Johnnie

Ajout à la réponse de Johnnie:

Utilisation youtube-dl -g "URL" pour obtenir les flux vidéo et audio.

Utilisez maintenant:

ffmpeg -ss 12:15 -i "1st-URL" -ss 12:15 -i "2nd-URL" -t 5:15 -map 0:v -map 1:a -c:v libx264 -c:a aac output.mkv

Vous devrez utiliser le -ss option pour chaque flux. Je recommande également de le faire environ 30 secondes plus tôt, puis d'utiliser un autre -ss 30 pour éviter de perdre des images clés. Voici un exemple réel en utilisant une de mes vidéos YouTube.

Vidéo

youtube-dl -g https://www.youtube.com/watch?v=gESHIrvIQQo

Production:

https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/298/source/youtube/requiressl/yes/mn/sn-mv-cvne/ei/BgifWfmmL4iE8wSlv47oCA/mm/31/pl/23/mv/m/ms/au/initcwndbps/11447500/ratebypass/yes/mime/video%2Fmp4/otfp/1/gir/yes/clen/5231968228/lmt/1502479662079137/dur/18575.164/key/dg_yt0/signature/4FFB9B0B7E1703B31F5D07DAD579B55F17EF7BAA.0CB63905C89DD4D33F90CF3AAD728F1ECDFCB9B3/mt/1503594423/ip/206.34.122.70/ipbits/0/expire/1503616102/sparams/ip,ipbits,expire,id,itag,source,requiressl,mn,ei,mm,pl,mv,ms,initcwndbps,ratebypass,mime,otfp,gir,clen,lmt,dur/
https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/140/source/youtube/requiressl/yes/mn/sn-mv-cvne/ei/BgifWfmmL4iE8wSlv47oCA/mm/31/pl/23/mv/m/ms/au/initcwndbps/11447500/ratebypass/yes/mime/audio%2Fmp4/otfp/1/gir/yes/clen/295235970/lmt/1502480001536214/dur/18575.243/key/dg_yt0/signature/4CD42047D1D5C714377350905C1CC5CBA37C0009.6EED1FC92D17A096235C32E48F4B15DEF7DD99B0/mt/1503594423/ip/206.34.122.70/ipbits/0/expire/1503616102/sparams/ip,ipbits,expire,id,itag,source,requiressl,mn,ei,mm,pl,mv,ms,initcwndbps,ratebypass,mime,otfp,gir,clen,lmt,dur/

Je voulais couper de 43h00 à 50h10 donc je vais faire -ss 42:30 (en me donnant quelques secondes pour capturer une bonne image clé) sur les deux entrées, puis faites un -ss 30 après les entrées pour commencer à 43:00.

Je vais ensuite utiliser map pour mapper la vidéo 0:v et audio 1:a (0 signifie la première entrée, qui est la vidéo et 1 signifie la deuxième entrée, qui est l'audio), puis choisissez mes options d'encodage.

# The first URL
video_url="https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/298/source/youtube/requiressl/yes/pl/23/ei/5wCfWY6dBeOj8gSSxZaACQ/mv/m/initcwndbps/5055000/ms/au/mm/31/mn/sn-mv-cvne/ratebypass/yes/mime/video%2Fmp4/otfp/1/gir/yes/clen/5231968228/lmt/1502479662079137/dur/18575.164/key/dg_yt0/beids/%5B9466591%5D/mt/1503592562/signature/8CCFBF5CAB97341D0CB1F34E85AB6EE20FC7A03E.7679F39A8603CF41A95F10232E2A921EB0774101/ip/206.34.122.70/ipbits/0/expire/1503614279/sparams/ip,ipbits,expire,id,itag,source,requiressl,pl,ei,mv,initcwndbps,ms,mm,mn,ratebypass,mime,otfp,gir,clen,lmt,dur/"
# The second URL
audio_url="https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/140/source/youtube/requiressl/yes/pl/23/ei/5wCfWY6dBeOj8gSSxZaACQ/mv/m/initcwndbps/5055000/ms/au/mm/31/mn/sn-mv-cvne/ratebypass/yes/mime/audio%2Fmp4/otfp/1/gir/yes/clen/295235970/lmt/1502480001536214/dur/18575.243/key/dg_yt0/beids/%5B9466591%5D/mt/1503592562/signature/4AACC8E27F9036D36D4D623A771A9F2BAC4674BA.7E4F4FB4DC023E3FE491A991F0F9F2329648DE9D/ip/206.34.122.70/ipbits/0/expire/1503614279/sparams/ip,ipbits,expire,id,itag,source,requiressl,pl,ei,mv,initcwndbps,ms,mm,mn,ratebypass,mime,otfp,gir,clen,lmt,dur/"
ffmpeg -ss 42:30 -i "$video_url" -ss 42:30 -i "$audio_url" -map 0:v -map 1:a -ss 30 -t 7:10 -c:v libx264 -c:a aac gog-vs-triv.mkv
33
godofgrunts
ffmpeg $(youtube-dl -g 'https://www.youtube.com/watch?v=oHg5SJYRHA0' | sed "s/.*/-ss 00:05 -i &/") -t 01:00 -c copy out.mkv
27
Steve Goranson

Cette demande de fonctionnalité n'est pas encore implémentée dans youtube-dl. Voir problème # 622 et de nombreux doublons sur github.

14
ks1322

youtube-dl prend en charge la transmission d'arguments au postprocesseur sous-jacent (testé avec la version 2017.08.27.1):

youtube-dl -x --postprocessor-args "-ss 00:13:00.00 -t 00:04:00.00" https://youtu.be/...

Cela revient à faire le post-traitement avec ffmpeg vous-même après avoir téléchargé le fichier en premier.

13
Kevin

Cela ne répond pas complètement à la question d'OP, mais il existe un moyen de télécharger un flux du début à une durée spécifique sans avoir à télécharger le flux complet. Étant donné que YouTube prend en charge les CV, nous pouvons demander un contenu partiel en utilisant l'en-tête Range.

Nous récupérons d'abord les URL des flux:

$ youtube-dl -g https://www.youtube.com/watch?v=yysk8s2vih8
https://r1---sn-npoeenee.googlevideo.com/videoplayback?source=youtu...
https://r1---sn-npoeenee.googlevideo.com/videoplayback?source=youtu...

Cela devrait produire deux URL (chacune pour les flux vidéo et audio).

Envoyez maintenant une requête principale à la première URL (qui est liée au flux vidéo) pour récupérer la longueur totale du contenu de ce flux:

$ curl "1st-URL" -sI | grep Content-Length
Content-Length: 64380504

Maintenant, nous divisons cette durée totale de contenu par le nombre total de secondes dans la vidéo (la vidéo YouTube a une durée de 4 minutes et 7 secondes, soit 247 secondes) pour obtenir approximativement la durée du contenu de 1 seconde:

64380504 / 247 ≈ 260650

Nous multiplions cette valeur par (nombre de secondes que nous voulons récupérer depuis le début + 1)

(nous en ajoutons un pour également tenir compte approximativement de l'espace supplémentaire pris par les métadonnées qui est placé au début du flux)

Par exemple, pour récupérer environ les 10 premières secondes, vous devrez récupérer le premier 260650 * 11 = 2867150 octets, donc nous faisons une demande avec l'en-tête Range:

$ curl "1st-URL" -H "Range: bytes=0-2867150" -o ten_secs.mp4

Cela ne devrait télécharger que les 10 premières secondes. Le fichier téléchargé devrait pouvoir être lu, mais il est préférable de laisser FFmpeg corriger les métadonnées incorrectes:

$ ffmpeg -i ten_secs.mp4 -c copy corrected_ten_secs.mp4

Nous pouvons également télécharger uniquement la partie initiale de l'audio (2e URL) de la même manière (la durée du contenu serait différente mais le nombre total de secondes resterait le même).

Le téléchargement de toute partie médiane de la vidéo devrait également être possible de cette manière, mais cela est probablement beaucoup plus délicat car YouTube place les métadonnées au début du flux (dans les premiers octets) et sans qu'il soit présent dans le support téléchargé, le le flux ne jouera pas du tout.

EDIT: Cela ne fonctionnera que sur les sites Web avec prise en charge des CV, par exemple YouTube. Cela ne fonctionnera pas pour d'autres sites Web.

4
ritiek

Utilisez le paramètre - postprocessor-args pour passer la sortie audio/vidéo à ffmpeg à éditer (le processeur), vous devez donc installer ffmpeg.

- postprocessor-args prend 3 arguments et valeurs (par exemple, il y en a plus, consultez la page de manuel de ffmpeg):

  • -ss HH: MM: SS: heure de début à prendre
  • -à HH: MM: SS: heure de fin
  • -t HH: MM: SS: durée à prendre

Exemples:

  • Commencez l'encodage à 15 secondes et arrêtez à 1 minutes 20 secondes

$ youtube-dl --postprocessor-args "-ss 0: 0: 15 -to 0: 1: 20" '[video_URL]'

  • Commencez l'encodage à 15 secondes et ne prenez que les 3 minutes 5 secondes suivantes

$ youtube-dl --postprocessor-args "-ss 0: 0: 15 -t 0: 3: 5" '[video_URL]'

PS: youtube-dl téléchargera l'intégralité du média avant de le traiter et le supprimera après.

4
niainaLens

Vous pouvez télécharger du début à un point sans télécharger le tout et éditer. C'est la moitié de ce que cette question demande:

interrompre le téléchargement avec ^C

  • Je n'ai essayé qu'avec mp4
  • ne fonctionnera pas avec une vidéo et un audio séparés, vous avez besoin d'un format avec les deux. Par défaut, ytdl obtient souvent une vidéo et un son séparés, puis les fusionne. Utilisation -F pour voir les formats disponibles et choisissez un mp4 qui a les deux. par exemple. -f18 ou -f22 sont généralement là.
  • vous devrez estimer à partir du pourcentage téléchargé (qui n'est pas linéaire; le taux de compression varie dans le temps).

Oui. C'est un hack .

Autre question: si vous voulez les formats vidéo et audio séparés, pourriez-vous télécharger une partie de chacun séparément (en utilisant ^c comme ici), puis les fusionner manuellement? Je ne pense pas que cela fonctionnera pour certains formats.

3
hyperpallium

J'ai fait un script implémentant la réponse @godofgrunts ici

#!/bin/bash
#taken from https://unix.stackexchange.com/a/388148/48971

if [ $# -lt 4 ]; then
        echo "Usage: $0 <youtube's URL> <HH:mm:ss from time> <HH:mm:ss to time> <output_file_name>"
        echo "e.g.:"
        echo "$0 https://www.youtube.com/watch?v=T1n5gXIPyws 00:00:25 00:00:42 intro.mp4"
        exit 1
fi

echo "processing..."

from=$(date "+%s" -d "UTC 01/01/1970 $2")
to=$(date "+%s" -d "UTC 01/01/1970 $3")

from_pre=$(($from - 30))

if [ $from_pre -lt 0 ]
then
        from_pre=0
fi

from_pre_command_print=$(date -u "+%T" -d @$from_pre)
from_command_print=$(date -u "+%T" -d @$(($from - $from_pre)))$(grep -o "\..*" <<< $2)
to_command_print=$(date -u "+%T" -d @$(($to - $from_pre)))$(grep -o "\..*" <<< $3)

command="ffmpeg "

for uri in $(youtube-dl -g $1)
do
        command+="-ss $from_pre_command_print -i $uri "
done

command+="-ss $from_command_print -to $to_command_print $4"
echo "downloading with the following command:"
echo "$command" 
$command

Je l'ai également téléchargé sur les extraits de Gitlab

1
Nico Rodsevich

J'ai fait une application flask qui peut à ce que vous voulez. Je sais que le message est ancien, mais le problème persiste.

Vous pouvez le trouver ici

Il peut également analyser le texte des liens YouTube. Vous venez de fournir par exemple:

YouTube.com/blahblah start-1:20

Cela téléchargera une vidéo de 0 à 1: 22 (de légères différences peuvent survenir à cause des images clés). Il peut également télécharger des vidéos entières, simplement omettre l'intervalle de temps dans ce cas.

0
DinRigtigeFar

Quelqu'un a créé un script batch (pour Windows) qui télécharge le fichier et extrait la partie souhaitée:

@ECHO off

:Input
ECHO.
SET url=
ECHO Enter Youtube-url:
SET /P url=
IF "%url%" EQU "" GOTO End
IF "%url: =%" NEQ "%url%" GOTO Input
ECHO Enter start time (in seconds, or in hh:mm:ss[.xxx] form):
SET /P start=
ECHO Enter duration (in seconds, or in hh:mm:ss[.xxx] form):
SET /P dur=
ECHO.
FOR /F "delims==" %%A IN ('youtube-dl.exe --no-warnings --get-filename "%url%"') DO SET filename=%%A
FOR /F %%B IN ('youtube-dl.exe -g "%url%"') DO (
ffmpeg.exe -hide_banner -ss "%start%" -i "%%B" -c copy -t "%dur%" "%filename%"
)
GOTO Input

:End
0
Jugurtha