El canal oficial de Power Rangers en YouTube tiene tres transmisiones en vivo diarias. También tiene un montón de material como los episodios completos y temporadas enteras de la serie clásica y sucesivas versiones. A veces está bueno engancharse a mirar una de estas transmisiones. Es como emular la forma en que uno miraba televisión en otras épocas, prendíamos la tele y mirábamos lo que había, sin tener idea el número de temporada o episodio.

Power Rangers Official YouTube

Procrastinando una noche en la que debía acostarme temprano para estar bien descansado para un evento que me venía produciendo bastante ansiedad, me puse a programar el siguiente script. Seguramente haya mejores maneras de hacer esto, más eficientes, y hasta más cómodas. Pero no es el punto, el ejercicio de definir un objetivo y lograrlo, por más intrascendente, ineficiente o innecesario que sea, a veces es una necesidad para apagar las voces de esos fantasmas que cargamos con nosotros. Ese esfuerzo ayuda a darle algo de significado a esos minutos vividos y compartirlo por este medio con suerte genere alguna reacción o conexión con la persona del otro lado de la pantalla. O al menos entretiene y distrae.

Es un script en Ruby que usa Nokogiri y OpenURL para descargar la página inicial de "en vivo" de Power Rangers en YouTube. De ahí, parsea los tres más nuevos. Por lo que he visto hasta ahora, son los que están "activos", y después van quedando archivados. Una vez obtenido el id del video, ejecuta VLC en pantalla completa y reproduce el stream desde YouTube (sin anuncios ni cookies y demás).

Lo comparto acá por si a alguien más le resulta útil o de repente inspira a usar algo de esto en otra cosa:

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'nokogiri'
  gem 'debug'
end

require 'json'
require 'nokogiri'
require 'open-uri'

url = 'https://www.youtube.com/@PowerRangersOfficial/streams'

doc = Nokogiri::HTML5(URI.open(url))
data = doc.xpath("//script").find do |c|
  c.children&.first&.text&.include?('var ytInitialData')
end.text
data.gsub!('var ytInitialData = ', '')
data.gsub!(/;$/, '')
coso = JSON.parse(data)

lives = coso['contents']['twoColumnBrowseResultsRenderer']['tabs'].find do |tab|
  tab['tabRenderer']['title'] == 'Live'
end

# Elegir uno al azar de los últimos 3

id = lives['tabRenderer']['content']['richGridRenderer']['contents'][(0..2).to_a.sample]['richItemRenderer']['content']['videoRenderer']['videoId']

# Elegir el stream con el título "Best Episodes" para mirar un compilado de mejores episodios

id = lives['tabRenderer']['content']['richGridRenderer']['contents'].find do |live|
  live['richItemRenderer']['content']['videoRenderer']['title']['runs'][0]['text'].include? 'Best Episodes'
end['richItemRenderer']['content']['videoRenderer']['videoId']

system("vlc -f https://www.youtube.com/watch?v=#{id}")

En principio tuve que parsear el HTML, y después encontrar una etiqueta script que contuviera el código var ytInitialData. Aparentemente esa variable JavaScript ytInitialData es la que guarda toda la información que usa la página web para mostrar los videos. Está en formato JSON, así que no tenía que andar haciendo encantamientos mágicos para manipular el texto. Accedí al texto dentro de las etiquetas, eliminé la parte inicial var ytInitialData = y el ; al final, y me quedaban llaves que definían JSON que pude parsear con JSON.parse en Ruby. Ahí ya podía empezar a navegar por llaves de Hashes hasta llegar al id del video. Como se ve en el código, está enterrado dentro de un montón de información, pero con un poco de debugging y prueba y error, lo encontré.

Algo interesante fue que programé este script en mi televisor, donde tengo una computadora conectada. Tengo Emacs "de fábrica", porque nunca me tomé el tiempo de configurarlo. Quién sería tan estúpido de ponerse a programar directamente en esa tele cuando puedo acceder con mi laptop por SSH... ¡YO! Me pareció divertido programar directamente e ir probando el resultado. De ahora en más los scripts los voy a mantener en la laptop para programar más cómodo...

View on Mastodon

Bonus track: Pokémon

El canal de Pokémon TV en YouTube tiene los mismos estilos de transmisión en vivo con capítulos de la serie animada. Hay uno en inglés y otro ¡en Español de Latinoamérica! También cuentan con un montón de listas de reproducción con temporadas completas, en varios idiomas, incluido también Español de Latinoamérica. Por lo tanto, se podría hacer algo similar, aunque aparentemente la id del video no cambia tanto, por lo que tengo un acceso directo (archivo .desktop) en mi escritorio con el siguiente código:

[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Exec=vlc -f https://www.youtube.com/watch?v=-UzJLeNuils
Name=Pokémon TV
Icon=/home/fernando/Documents/pokemontv.jpg

Al hacer clic, se abre VLC en pantalla completa con el parámetro -f de línea de comando y reproduce la URL de YouTube que le paso. También, si uno quisiera "archivar" estos videos ofrecidos gratis y públicos, para mirarlos más tarde desde un dispositivo donde no contamos con conexión a internet, o tenerlos de respaldo en caso de que se caiga internet, o YouTube haya dejado de existir, o vivamos en un mundo post-apocalíptico donde no hay Internet pero sí suficiente electricidad de sobra como para usarla en computadoras como medio de entretenimiento y quisiéramos volver a mirar capítulos de Pokémon para recordar nuestras infancias y escapar de esta distópica realidad por unos meros minutos, uno podría ejecutar yt-dlp_linux --audio-multistreams -f bestvideo+bestaudio+233-3 https://www.youtube.com/playlist?list=PLRcHmntfmJ8CnSmj4C284-a1euH518aQa en la terminal para obtener todos los capítulos de la primera temporada con doble pista de audio en inglés y español de Latinoamérica.

Me gusta esto de programar cosas que puedo usar en la tele, hace unos años creé un control remoto web para volúmen. Otro proyecto totalmente innecesario, pero muchas veces es más importante probar que algo funciona, que su eventual utilidad. Debería reveer ese proyecto para ver cómo lo implementaría éstos días 🤔

No hay comentarios en este post

Feed de comentarios

Dejar un comentario

Toasty!