2

I'm trying to download an entire Youtube channel and that worked.

But I'm having the directories' names like below and thus I need to change that all manually.

I need a way to pass channel / playlist name and id to the script instead of fetching the url.

Script I used :

# get working/beginning directory
l=$(pwd);
clear;
# get playlists data from channel list
youtube-dl -j --flat-playlist \
  "https://www.youtube.com/channel/UC-QDfvrRIDB6F0bIO4I4HkQ/playlists" \
  |cut -d ' ' -f4 \
  |cut -c 2-73 \
  |while IFS= read -r line;
  do;
    # loop: do with every playlist link
    # make a directory named by the playlist identifier in url
    mkdir ${line:38:80};
    # change directory to new directory
    cd $l/${line:38:80};
    # download playlist
    youtube-dl -f mp4 "$line";
    # print playlist absolute dir to user
    pwd;
    # change directory to beginning directory
    cd $l;
  done;

Names of directories :

.
├── PLxl69kCRkiI0oIqgQW3gWjDfI-e7ooTUF
├── PLxl69kCRkiI0q0Ib8lm3ZJsG3HltLQDuQ
├── PLxl69kCRkiI1Ebm-yvZyUKnfoi6VVNdQ7
├── ...
└── PLxl69kCRkiI3u-k02uTpu7z4wzYLOE3sq


This is not working :

  1. https://github.com/ytdl-org/youtube-dl/issues/23442

    # any playlist is seen as private
    youtube-dl -J \
      https://m.youtube.com/playlist?list=PL3GeP3YLZn5jOiHM8Js1_S0p_5HeS7TbY \
      | jq -r '.title'
    
  2. How to use youtube-dl from a python program?

    I need it for bash script not for python


Edit: simply explained

How to get channel name from bash youtube-dl and replace it with list id for file name in this script

12
  • Remember about quotes. Rule of a thumb: every time you do $var add quotes "$var". not working - what does it mean it's "not working"? I don't understand, what exactly do you want to pass to your script? Can you give an example? You want to pass PL3GeP3YLZn5jOiHM8Js1_S0p_5HeS7TbY and in result your script scould know the channel name? How is the not working code snipped related?
    – KamilCuk
    Commented Jan 9, 2020 at 12:33
  • thought that also Commented Jan 9, 2020 at 13:51
  • 2
    $ youtube-dl -J --no-warnings "https://www.youtube.com/playlist\?list\=PLXmMXHVSvS-CoYS177-UvMAQYRfL3fBtX" | jq -r '.title' Commented Jan 9, 2020 at 13:51
  • ERROR: Unable to download webpage: HTTP Error 404: Not Found (caused by <HTTPError 404: 'Not Found'>); please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see https://yt-dl.org/update on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output. Commented Jan 9, 2020 at 13:52
  • 1
    Ever notice how hard a really long one-line script can be to debug? If this script is useful over time, you will curse the person who wrote it as you do the necessary maintenance. Stay on the right side of future you and break this script into testable functions.
    – Mike Slinn
    Commented Apr 17, 2021 at 23:54

1 Answer 1

3

Consider the following:

#!/usr/bin/env bash

# if we don't delete slashes from titles there are serious security issues here
slash=/

# note that this url, being in quotes, needs no backslash escaping.
url='https://www.youtube.com/playlist?list=PLXmMXHVSvS-CoYS177-UvMAQYRfL3fBtX'

# First, get the name for the whole playlist
playlist_title=$(youtube-dl -J --flat-playlist "$url" | jq -r .title) || exit

# ...and, for the rest of the script, work under a directory named by that title
mkdir -p -- "${playlist_title//$slash/}" || exit
cd "${playlist_title//$slash/}" || exit

# Finally, loop over the individual videos and download them one at a time.
# ...arguably, you could tell youtube-dl to do this itself; call it an exercise.
youtube-dl -j --flat-playlist "$url" |   # one JSON document per playlist entry
  jq -r '[.id, .title] | @tsv' |         # write id, then title, tab-separated
  while IFS=$'\t' read -r id title; do ( # read that id and title from jq
      # because of the ()s, this is a subshell; exits just go to the next item
      # ...which is also why exec doesn't end the entire script.
      dir=${title//$slash/} # take slashes out of the title to form directory
      mkdir -p -- "$dir" || exit
      cd -- "$dir" || exit  # if cd fails, do not download anything
      exec youtube-dl "$id" # exec is a minor perf optimization; consume subshell
  ); done

Note:

  • We're using jq to convert the JSON to a more safely-readable format that we can parse without byte offsets.
  • The extra backslashes were removed from the URL to prevent the 404 error described in the comments to the question.
  • Putting the body of the loop in a subshell with parenthesis means that the cd inside that subshell is automatically reversed when the parenthesized section is exited.
  • We don't trust titles not to contain slashes -- you don't need someone naming their video /etc/sudoers.d/hi-there or otherwise placing files in arbitrarily-chosen places.
  • Note the use of "$dir" instead of just $dir. That's important; see shellcheck warning SC2086.
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.