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?
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.
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.
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
ffmpeg $(youtube-dl -g 'https://www.youtube.com/watch?v=oHg5SJYRHA0' | sed "s/.*/-ss 00:05 -i &/") -t 01:00 -c copy out.mkv
Cette demande de fonctionnalité n'est pas encore implémentée dans youtube-dl. Voir problème # 622 et de nombreux doublons sur github.
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.
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.
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):
Exemples:
$ youtube-dl --postprocessor-args "-ss 0: 0: 15 -to 0: 1: 20" '[video_URL]'
$ 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.
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
mp4
-F
pour voir les formats disponibles et choisissez un mp4
qui a les deux. par exemple. -f18
ou -f22
sont généralement là.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.
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
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.
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