How to enable YouTube autoplay with youtube-dl & mpv

autoplaympvyoutubeyoutube-dl

Is there a way to play a video and make it follow YouTube autoplay videos?

Can this be done with youtube-dl and/or mpv?

Best Answer

simplified approach

you could use a small script:

#!/usr/bin/perl
use strict;
use warnings;

my $id = $ARGV[0] or die "youtube ID as param needed"; 
$id =~ s/.*v=//;
my $yt = "https://www.youtube.com/watch?v="; 
while(1){
    `mpv $yt$id`; 
    ($id) = `wget -q -O- "$yt$id"` =~ /"autoplay":\{.*?"videoId":"([^"]+)"/; 
    print "$id\n";
}

save this as autoplay.pl, call chmod 755 autoplay.pl, and then try e.g. ./autoplay.pl 5YTxsc3Cz24

or, directly in your shell:

perl -e 'my $id="5YTxsc3Cz24"; my $yt = "https://www.youtube.com/watch?v="; while(1){`mpv $yt$id`; ($id) = `wget -q -O- "$yt$id"` =~ /"autoplay":\{.*?"videoId":"([^"]+)"/; print "$id\n";}'

you can end the playing by pressing ctrl+c (two times, one for mpv, one for the script).

avoid recurring IDs

the above code is a basic example and does not avoid any loops. if you want to avoid playing videos with the same ID twice, this can be achieved by adding a bucket:

#!/usr/bin/perl
use strict;
use warnings;

my $id = $ARGV[0] or die "youtube ID or youtube url as param needed"; 
$id =~ s/.*v=//;
my $yt = "https://www.youtube.com/watch?v="; 
my %bucket = ($id => 1);
while(defined $id){
    print "$id\n";
    `mpv $yt$id`; 
    my @ids = `wget -q -O- "$yt$id"` =~ /"videoId":"([^"]+)"/g; 
    undef $id;
    for my $i(@ids){
        unless($bucket{$i}){
            $id = $i;
            ++$bucket{$id};
        }
    }
}

this code searches the current youtube page for all IDs and skips those IDs already played. it ends, if no unplayed ID is found at the current page.

avoid recurring IDs harder

however, in some rare(?) cases you might have played all IDs of the current youtube page already. then the script should look up the pages of already seen IDs:

#!/usr/bin/perl
use strict;
use warnings;

my $id = $ARGV[0] or die "youtube ID or youtube url as param needed"; 
$id =~ s/.*v=//;
my $yt = "https://www.youtube.com/watch?v="; 
my %bucket = ($id => 1);

sub get_new_videoID{
    my $id = shift;
    my @ids = `wget -q -O- "$yt$id"` =~ /"videoId":"([^"]+)"/g; 
    my $new_id;
    for my $i(@ids){
        unless($bucket{$i}){
            ++$bucket{$i};
            $new_id = $i;
            last;
        }
    }
    return $new_id;
}

sub search_seen_videos{
    my @seen_IDs = keys %bucket;
    my $new_id;
    for my $id(@seen_IDs){
        $new_id = get_new_videoID($id);
        last if defined $new_id;
    }
    return $new_id;
}

while(defined $id){
    print "$id\n";
    `mpv $yt$id`; 
    $id = get_new_videoID($id) // search_seen_videos();
}
print "you have watched all related videos. better do something else now.\n";