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

64

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

Je souhaite télécharger uniquement une partie de la vidéo trop longue. Je souhaite donc ne télécharger que quelques minutes de la vidéo. Exemple de 13 minutes à 17 minutes.

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

utilisateur3181614
la source

Réponses:

46

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

Commencez par acquérir l'URL actuelle à l'aide de youtube-dl:

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

Copiez le résultat de la commande et collez-le dans le -iparamètre de la commande suivante:

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

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

ffmpeg est un outil populaire et devrait figurer dans n’importe quel référentiel de système d’exploitation / gestionnaires de paquetages populaires.

Johnnie
la source
8
Vous devez donc essentiellement télécharger la vidéo entière et la rogner vous
Antony
12
Vous pouvez utiliser l'option -to au lieu de -t si vous souhaitez spécifier l'heure de fin de la tranche de vidéo. ffmpeg -i "OUTPUT-OF-FIRST URL" -ss 00:13:00.00 -to 00:17:00.00 -c copy out.mp4
ˆᵛˆ
5
@Antony ffmpegne téléchargera que la partie que vous spécifiez.
akaihola
Il n'a pas enregistré audio pour une vidéo dans mon cas contrairement à @godofgrunts répondre.
daGo
19
ffmpeg $(youtube-dl -g 'https://www.youtube.com/watch?v=oHg5SJYRHA0' | sed "s/.*/-ss 00:05 -i &/") -t 01:00 -c copy out.mkv
Steve Goranson
la source
5
Pourriez-vous expliquer ce que ça fait, comment ça marche?
user259412
3
Il ne s'agit que d'une version plus concise de la réponse @godofgrunts, qui utilise sed pour gagner du temps, en récupérant manuellement les URL et en les copiant / collant aux heures de début (-ss 00:05). @godofgrunts a quelques drapeaux supplémentaires -map 0:v -map 1:a -c:v libx264 -c:a aacqui pourraient améliorer la qualité. J'aime aussi ajouter youtube-dl -f bestvideo+bestaudiopour être sûr d'obtenir la version de la plus haute qualité.
Steve Goranson
ffmpeg.zeranoe.com/builds pour Windows.
Wolfpack'08
18

Ajout à la réponse de Johnnie:

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

Maintenant, utilisez:

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 l' -ssoption pour chaque flux. Je recommande également de le faire environ 30 secondes plus tôt, puis d’en utiliser un autre -ss 30pour éviter de perdre des images clés. Voici un exemple réel utilisant l'une de mes vidéos youtube.

Vidéo

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

Sortie:

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 43:00 à 50:10 alors je vais faire -ss 42:30(en me laissant quelques secondes pour saisir une bonne image clé) sur les deux entrées puis faire un -ss 30après les entrées pour commencer à 43:00.

Je vais ensuite utiliser mappour mapper la vidéo 0:vet l'audio 1:a(0 correspond à la première entrée, qui est la vidéo et 1 à la deuxième entrée, qui est l'audio), puis je choisis mes options d'encodage.

ffmpeg -ss 42:30 -i "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/" -ss 42:30 -i "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/" -map 0:v -map 1:a -ss 30 -t 7:10 -c:v libx264 -c:a aac gog-vs-triv.mkv
Godofgrunts
la source
1
Merci. Je ne savais pas comment obtenir un son, pour @Johnnie post. Votre message y a répondu.
Manny_Mar
Wow, je ne savais pas que le -idrapeau de ffmpeg pouvait prendre les URL. soigné
Geremia
En quoi diffère-t-il de l'utilisation --postprocessor-argsdirecte dans youtube-dl?
daGo
13

Cette demande de fonctionnalité n'est pas encore implémentée dans youtube-dl. Voir le numéro 622 et de nombreux doublons sur github.

ks1322
la source
10

youtube-dl prend en charge le passage d'arguments au post-processeur 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 fondamentalement à faire le post-traitement avec ffmpegvous-même après le téléchargement du fichier.

Kevin
la source
4
mais cela nécessitera toujours de télécharger la vidéo entière, puis coupez la partie souhaitée
Kasparov92
Je reçois une unable to obtain file audio codec with ffprobeerreur. Pouvez-vous m'aider s'il vous plaît avec cela. J'utilise CentOS 7
Hassaan
3
Notez que le -xdrapeau télécharge uniquement l'audio. Omettez-le de la commande si vous voulez à la fois l'audio et la vidéo. :)
grooveplex
2

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

interrompre le téléchargement avec ^C

  • J'ai seulement essayé avec mp4
  • ne fonctionnera pas avec vidéo et 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. Utilisez -Fpour voir les formats disponibles, et choisissez un mp4qui a les deux. par exemple -f18ou -f22sont généralement là.
  • vous devrez estimer à partir du pourcentage téléchargé (ce qui n'est pas linéaire, le taux de compression varie dans le temps).

Oui. C'est un bidouillage .

Question supplémentaire: si vous souhaitez des formats audio et vidéo distincts, pouvez-vous télécharger une partie de chacun séparément (en utilisant la méthode ^cdécrite ici), puis les fusionner manuellement? Je ne pense pas que cela fonctionnera pour certains formats.

hyperpallium
la source
2

Cela ne répond pas complètement à la question de 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 fournit un support de résumé, nous pouvons demander un contenu partiel en utilisant l'en- Rangetête.

Nous allons d'abord chercher les URL de 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 générer deux URL (chacune pour les flux vidéo et audio).

Envoyez maintenant une requête à la première URL (qui renvoie au flux vidéo) pour extraire la longueur totale du contenu de ce flux:

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

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

64380504 / 247 ≈ 260650

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

(Nous en ajoutons un pour également prendre en compte approximativement l'espace supplémentaire pris par les métadonnées placées au début du flux)

Par exemple, pour récupérer environ les 10 premières secondes, vous devrez récupérer les premiers 260650 * 11 = 2867150octets. Nous faisons donc une requête avec l'en- Rangetête:

$ 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 vaut mieux laisser FFmpeg réparer 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 (2ème URL) d'une manière similaire (la longueur du contenu serait différente mais le nombre total de secondes resterait identique).

Le téléchargement de toute partie centrale de la vidéo devrait également être possible de cette manière, mais cela risque d’être beaucoup plus compliqué, car YouTube place les métadonnées au début du flux (dans les premiers octets) et, sans que cela soit présent dans les médias téléchargés, stream ne jouera pas du tout.

EDIT: Cela ne fonctionnera que sur des sites Web avec support de CV, par exemple YouTube. Cela ne fonctionnera pas pour d'autres sites.

ritiek
la source
1

Utilisez le paramètre --postprocessor-args pour transmettre la sortie audio / vidéo à ffmpeg à modifier (le processeur). Ffmpeg doit donc être installé.

--postprocessor-args prend 3 arguments et valeurs (par exemple, c'est 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-vous à 1 minute 20 secondes

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

  • Commencez à encoder à 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 support avant de le traiter et le supprimera ensuite.

niainaLens
la source
1

J'ai fait un script implémentant @godofgrunts répondre 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ée dans les extraits de Gitlab .

Nico Rodsevich
la source