Schlagwort-Archive: M3U

YouTube Watch Later als M3U-Playlist exportieren

Ein großer Teil meines Medienkonsums läuft über YouTube. Bastler, Podcasts, Vorträge – nahezu alles ist hier vorhanden und hat den Fernseher nahezu vollständig abgelöst. Eine der aufwändigsten Arbeiten für mich ist es meine „Wunschliste“ an Videos zu verwalten. Welche Videos möchte ich mir noch ansehen. Hierzu nutze ich bereits seit längerem einige Scripte um Posts diverser Channels zu sortieren und Interessantes in die „Watch Later“-Liste, also „Später ansehen“, zu verschieben. Diese kann ich dann einfach auf dem Tablet laufen lassen und so die Videos nach und nach ansehen.

Anders sieht es aus wenn ich am PC arbeite. Zwar kann man auch hier die Liste über die Webseite nutzen, jedoch ist hier ohne Klimmzübe kein Overlay („Immer im Vordergrund“) möglich. Als Abhilfe nutze ich hier üblicherweise VLC – dort kann man eine YouTube-URL eingeben und direkt abspielen. Leider gibt es keine direkte Unterstützung für Playlisten und die verfügbaren Plugins lassen nur öffentliche Listen abrufen.

Bild:

Natürlich könnte ich jetzt meine Scripte umschreiben und öffentliche (bzw. „Nicht gelistete“) Listen nutzen, jedoch ist das manuelle Hinzufügen zur Watch-Later-List dank des überall verfügbaren Buttons wesentlich einfacher als das Hinzufügen zu selbst angelegten Listen.

Bild: https://adlerweb.info/blog/wp-content/uploads/2015/04/wll.png

Da ich von LUA, welches in VLC zum Einsatz kommt, keine Ahnung habe und durch meine sonstigen YT-Automationen tonnenweise fertigen PHP-Code zur Verfügung habe ist entsprechend eine Webanwendung daraus geworden. Benötigt wird ein API-Key, welcher in der Dev-Console beantragt werden kann sowie die Installation des Google API PHP-Client. Auch sollte der Webserver die Berechtigung haben key.php im selben Verzeichnis zu beschreiben – dies kann z.B. über „touch key.php ; chmod ugo+w key.php“ erfolgen. Der erste Aufruf sollte über den Browser erfolgen, hierbei wird man aufgefordert das Script mit YouTube zu Paaren. Die so abgerufenen Schlüssel werden in den angesprochenen key.php gespeichert, sodass folgende Zugriffe ohne weitere Abfragen erfolgen. Die URL kann nun in VLC eingefügt werden – dieser sollte die so bereitgestellte Playlist laden und die Videos nacheinander abspielen – mit allen Features des VLC wie z.B. Always-on-Top, Abspielgeschwindigkeit, Videoeffekte, etc.

Bild: https://adlerweb.info/blog/wp-content/uploads/2015/04/playlist-300×266.png

Den Code zum selbst testen gibts anbei oder – ohne WordPress-Korrekturversuche – im Gist. Eventuell ließ sich das Ganze auch noch mit youtube-dl kombinieren um einen Podcast-kompatiblen Feed zu erstellen.

< ?php

/**
 * Youtube Watch Later List To Playlist Script
 * 
 * This script fetches your watch later list and outputs it as an M3U playlist
 *
 * Requirements:
 *   PHP enabled webserver
 *   Google PHP API (https://github.com/google/google-api-php-client)
 *   A YouTube API key (Oauth2, can be registered at https://console.developers.google.com/)
 *   Some kittens to sacrifice
 *
 * Initialization
 *   First ensure your webserver can write a file called "key.php" to the directory
 *   you put this file in. E.g. "touch key.php ; chmod ugo+w key.php"
 *   Next open the appropriate URL in your browser. You will be asked to pair
 *   this script with your YouTube-Account. If you configured everything correctly
 *   it will output the playlist and save your access codes in the key.php mentioned
 *   above. Successive requests do not require additional authentication. You may now
 *   put the URL in your YT-enabled media player like VLC.
 *
 * Based on examples by DomSammut (https://www.domsammut.com/code/php-server-side-youtube-v3-oauth-api-video-upload-guide)
 * 2015 Florian Knodt 
 */ 

// Set this to the directory of google api php client
set_include_path('./google-api-php-client/src/');

$OAUTH2_CLIENT_ID = 'YOURID.apps.googleusercontent.com';
$OAUTH2_CLIENT_SECRET = 'YOURSECRET';
$REDIRECT = 'http://localhost/yt/ytwll2m3u.php';
$APPNAME = 'YouTube WLL Import Test';

require_once 'Google/autoload.php';
session_start();

$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setApplicationName($APPNAME);
$client->setAccessType('offline');

if(file_exists('key.php')) {
    require_once 'key.php';
}

if(isset($key)) {
    $client->setAccessToken($key);
    $_SESSION['token'] = $key;
}else{
    $client->setScopes('https://www.googleapis.com/auth/youtube');
    $client->setRedirectUri($REDIRECT);
}

// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);

if (isset($_GET['code'])) {
    if (strval($_SESSION['state']) !== strval($_GET['state'])) {
        die('The session state did not match.');
    }
 
    $client->authenticate($_GET['code']);
    $_SESSION['token'] = $client->getAccessToken();
 
}
 
if (isset($_SESSION['token'])) {
    $client->setAccessToken($_SESSION['token']);
    $keydata = '< ?php $key=\''.$_SESSION['token'].'\'; ?>';
    //echo '' . $_SESSION['token'] . '';
   
    if(!is_writable('key.php')) {
        die('key.php can not be written - please put this code into key.php: '.$keydata);
    }
    file_put_contents('key.php', $keydata);
}

// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
    try {
        // Call the channels.list method to retrieve information about the
        // currently authenticated user's channel.
        $channelsResponse = $youtube->channels->listChannels('contentDetails', array(
            'mine' => 'true',
        ));
 
        $playlist = '#EXTM3U'."\n";
        foreach ($channelsResponse['items'] as $channel) {
            // Extract the unique playlist ID that identifies the list of videos
            // uploaded to the channel, and then call the playlistItems.list method
            // to retrieve that list.
            $uploadsListId = $channel['contentDetails']['relatedPlaylists']['watchLater'];
 
            $playlistItemsResponse = $youtube->playlistItems->listPlaylistItems('snippet', array(
                'playlistId' => $uploadsListId,
                'maxResults' => 50
            ));
 
            foreach ($playlistItemsResponse['items'] as $playlistItem) {
                $playlist .= '#EXTINF:-1,'.$playlistItem['snippet']['title']."\n".'https://www.youtube.com/watch?v='.$playlistItem['snippet']['resourceId']['videoId']."\n";
            }
            
            while(isset($playlistItemsResponse['nextPageToken'])) {
                $playlistItemsResponse = $youtube->playlistItems->listPlaylistItems('snippet', array(
                    'playlistId' => $uploadsListId,
                    'maxResults' => 50,
                    'nextPageToken' => $playlistItemsResponse['nextPageToken'],
                ));
                foreach ($playlistItemsResponse['items'] as $playlistItem) {
                    //$htmlBody .= sprintf('
  • %s (%s)
  • ', $playlistItem['snippet']['title'], //$playlistItem['snippet']['resourceId']['videoId']); $playlist .= '#EXTINF:-1,'.$playlistItem['snippet']['title']."\n".'https://www.youtube.com/watch?v='.$playlistItem['snippet']['resourceId']['videoId']."\n"; } } } } catch (Google_ServiceException $e) { echo sprintf('

    A service error occurred: %s

    ', htmlspecialchars($e->getMessage())); } catch (Google_Exception $e) { echo sprintf('

    An client error occurred: %s

    ', htmlspecialchars($e->getMessage())); } $_SESSION['token'] = $client->getAccessToken(); } else { $state = mt_rand(); $client->setState($state); $_SESSION['state'] = $state; $authUrl = $client->createAuthUrl(); $htmlBody = < <Authorization Required

    You need to authorise access before proceeding.

    END; } if(isset($playlist)) die($playlist); ?> < !doctype html> My Uploads < ?php echo $htmlBody?>