require 'dotenv' require 'json' require 'open-uri' Dotenv.load class TumblrService TUMBLR_API_KEY = ENV["TUMBLR_API_KEY"] TUMBLR_API_SECRET = ENV["TUMBLR_API_SECRET"] TUMBLR_ACCESS_TOKEN = ENV["TUMBLR_ACCESS_TOKEN"] TUMBLR_ACCESS_TOKEN_SECRET = ENV["TUMBLR_ACCESS_TOKEN_SECRET"] TUMBLR_BLOG_URL = ENV["TUMBLR_BLOG_URL"] def initialize raise "TUMBLR_API_KEY is required" unless TUMBLR_API_KEY raise "TUMBLR_API_SECRET is required" unless TUMBLR_API_SECRET raise "TUMBLR_ACCESS_TOKEN is required" unless TUMBLR_ACCESS_TOKEN raise "TUMBLR_ACCESS_TOKEN_SECRET is required" unless TUMBLR_ACCESS_TOKEN_SECRET raise "TUMBLR_BLOG_URL is required" unless TUMBLR_BLOG_URL @tumblr = Tumblr::Client.new( :consumer_key => TUMBLR_API_KEY, :consumer_secret => TUMBLR_API_SECRET, :oauth_token => TUMBLR_ACCESS_TOKEN, :oauth_token_secret => TUMBLR_ACCESS_TOKEN_SECRET, ) end def post_image(image_path) @tumblr.photo(TUMBLR_BLOG_URL, {:data => [image_path]}) end end class YouTubeService YTDLP_PATH = `which yt-dlp`.chomp FFMPEG_PATH = `which ffmpeg`.chomp FFPROBE_PATH = `which ffprobe`.chomp VIDEO_PATH = "/tmp/video.mp4" FRAME_PATH = "/tmp/frame.png" PLAYLIST_ID = ENV["PLAYLIST_ID"] def initialize raise "PLAYLIST_ID is required" unless PLAYLIST_ID raise "Can't find youtube-dl" if YTDLP_PATH.empty? raise "Can't find ffprobe" if FFPROBE_PATH.empty? raise "Can't find ffmpeg" if FFMPEG_PATH.empty? end def fetch_random_frame_of_random_video download_random_video extract_frame delete_video FRAME_PATH end def download_random_video `#{YTDLP_PATH} --playlist-random --max-downloads 1 -o #{VIDEO_PATH} -f mp4 #{PLAYLIST_ID}` end def extract_frame random_second = rand(0..get_video_length) `#{FFMPEG_PATH} -v error -ss #{random_second} -i #{VIDEO_PATH} -frames 1 -y #{FRAME_PATH}` end def get_video_length `#{FFPROBE_PATH} -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 #{VIDEO_PATH}`.chomp.to_i end def delete_video `rm #{VIDEO_PATH}` end def delete_frame `rm #{FRAME_PATH}` end end youtube = YouTubeService.new image_path = youtube.fetch_random_frame_of_random_video tumblr = TumblrService.new tumblr.post_image(image_path) youtube.delete_frame