A Twitter bot that tweets random frames from the Computer Chronicles TV show https://twitter.com/chronicles_bot
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cc.rb 2.3KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. require 'dotenv'
  2. require 'json'
  3. require 'open-uri'
  4. Dotenv.load
  5. class TumblrService
  6. TUMBLR_API_KEY = ENV["TUMBLR_API_KEY"]
  7. TUMBLR_API_SECRET = ENV["TUMBLR_API_SECRET"]
  8. TUMBLR_ACCESS_TOKEN = ENV["TUMBLR_ACCESS_TOKEN"]
  9. TUMBLR_ACCESS_TOKEN_SECRET = ENV["TUMBLR_ACCESS_TOKEN_SECRET"]
  10. TUMBLR_BLOG_URL = ENV["TUMBLR_BLOG_URL"]
  11. def initialize
  12. raise "TUMBLR_API_KEY is required" unless TUMBLR_API_KEY
  13. raise "TUMBLR_API_SECRET is required" unless TUMBLR_API_SECRET
  14. raise "TUMBLR_ACCESS_TOKEN is required" unless TUMBLR_ACCESS_TOKEN
  15. raise "TUMBLR_ACCESS_TOKEN_SECRET is required" unless TUMBLR_ACCESS_TOKEN_SECRET
  16. raise "TUMBLR_BLOG_URL is required" unless TUMBLR_BLOG_URL
  17. @tumblr = Tumblr::Client.new(
  18. :consumer_key => TUMBLR_API_KEY,
  19. :consumer_secret => TUMBLR_API_SECRET,
  20. :oauth_token => TUMBLR_ACCESS_TOKEN,
  21. :oauth_token_secret => TUMBLR_ACCESS_TOKEN_SECRET,
  22. )
  23. end
  24. def post_image(image_path)
  25. @tumblr.photo(TUMBLR_BLOG_URL, {:data => [image_path]})
  26. end
  27. end
  28. class YouTubeService
  29. YTDLP_PATH = `which yt-dlp`.chomp
  30. FFMPEG_PATH = `which ffmpeg`.chomp
  31. FFPROBE_PATH = `which ffprobe`.chomp
  32. VIDEO_PATH = "/tmp/video.mp4"
  33. FRAME_PATH = "/tmp/frame.png"
  34. PLAYLIST_ID = ENV["PLAYLIST_ID"]
  35. def initialize
  36. raise "PLAYLIST_ID is required" unless PLAYLIST_ID
  37. raise "Can't find youtube-dl" if YTDLP_PATH.empty?
  38. raise "Can't find ffprobe" if FFPROBE_PATH.empty?
  39. raise "Can't find ffmpeg" if FFMPEG_PATH.empty?
  40. end
  41. def fetch_random_frame_of_random_video
  42. download_random_video
  43. extract_frame
  44. delete_video
  45. FRAME_PATH
  46. end
  47. def download_random_video
  48. `#{YTDLP_PATH} --playlist-random --max-downloads 1 -o #{VIDEO_PATH} -f mp4 #{PLAYLIST_ID}`
  49. end
  50. def extract_frame
  51. random_second = rand(0..get_video_length)
  52. `#{FFMPEG_PATH} -v error -ss #{random_second} -i #{VIDEO_PATH} -frames 1 -y #{FRAME_PATH}`
  53. end
  54. def get_video_length
  55. `#{FFPROBE_PATH} -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 #{VIDEO_PATH}`.chomp.to_i
  56. end
  57. def delete_video
  58. `rm #{VIDEO_PATH}`
  59. end
  60. def delete_frame
  61. `rm #{FRAME_PATH}`
  62. end
  63. end
  64. youtube = YouTubeService.new
  65. image_path = youtube.fetch_random_frame_of_random_video
  66. tumblr = TumblrService.new
  67. tumblr.post_image(image_path)
  68. youtube.delete_frame