Skip to content

Instantly share code, notes, and snippets.

@arubis
Last active October 11, 2024 04:31
Show Gist options
  • Save arubis/e80d191dcf6c50ba84d1315f61dae8fc to your computer and use it in GitHub Desktop.
Save arubis/e80d191dcf6c50ba84d1315f61dae8fc to your computer and use it in GitHub Desktop.
Youtube talk summarizer
#!/bin/bash
set -e
PROJECT_NAME="youtube_transcriber"
mkdir -p $PROJECT_NAME
cd $PROJECT_NAME
cat << EOF > Gemfile
source 'https://rubygems.org'
gem 'thor'
gem 'terrapin'
gem 'ruby-openai'
gem 'streamio-ffmpeg'
EOF
bundle install
cat << 'EOF' > transcriber.rb
#!/usr/bin/env ruby
require 'thor'
require 'terrapin'
require 'openai'
require 'fileutils'
require 'streamio-ffmpeg'
FFMPEG.ffmpeg_binary = `which ffmpeg`.strip
class TranscriptSummarizer < Thor
desc "process URL", "Download, transcribe, and summarize a YouTube video"
option :output, default: 'output', desc: 'Output directory'
def process(url)
setup_output_directory(options[:output])
video_path = download_video(url, options[:output])
transcript = transcribe_audio(video_path)
save_transcript(transcript, options[:output])
summary = generate_summary(transcript)
save_summary(summary, options[:output])
end
private
def setup_output_directory(output_dir)
FileUtils.mkdir_p(output_dir)
end
def download_video(url, output_dir)
puts "Downloading video..."
video_path = File.join(output_dir, 'video.mp3')
Terrapin::CommandLine.new("yt-dlp", "-x --audio-format mp3 -o :output :url").run(output: video_path, url: url)
video_path
end
def transcribe_audio(audio_path)
puts "Transcribing audio..."
client = OpenAI::Client.new(access_token: ENV['OPENAI_API_KEY'])
movie = FFMPEG::Movie.new(audio_path)
(0..movie.duration).step(600).map do |start_time|
end_time = [start_time + 600, movie.duration].min
chunk_path = "#{audio_path}_chunk_#{start_time}_#{end_time}.mp3"
movie.transcode(chunk_path, { seek_time: start_time, duration: end_time - start_time })
response = client.audio.transcribe(parameters: { model: "whisper-1", file: File.open(chunk_path, "rb") })
FileUtils.rm(chunk_path)
response['text']
end.join("\n\n")
end
def save_transcript(transcript, output_dir)
File.write(File.join(output_dir, 'transcript.txt'), transcript)
end
def generate_summary(transcript)
puts "Generating summary..."
summarize_with_gpt4(transcript)
rescue => e
puts "Error generating summary: #{e.message}"
transcript
end
def summarize_with_gpt4(transcript)
client = OpenAI::Client.new(access_token: ENV['OPENAI_API_KEY'])
transcript.scan(/.{1,14000}/m).map.with_index do |chunk, index|
puts "Summarizing chunk #{index + 1}..."
response = client.chat(parameters: {
model: "gpt-4",
messages: [
{ role: "system", content: "Summarize the following transcript part:" },
{ role: "user", content: chunk }
],
max_tokens: 500
})
response.dig("choices", 0, "message", "content") || raise("Unexpected response format")
end.join("\n\n")
end
def save_summary(summary, output_dir)
File.write(File.join(output_dir, 'summary.txt'), summary)
end
end
TranscriptSummarizer.start(ARGV)
EOF
chmod +x transcriber.rb
cat << EOF > README.md
# YouTube Transcriber and Summarizer
Transcribes and summarizes YouTube videos using OpenAI's Whisper and GPT-4.
## Setup
1. \`bundle install\`
2. Set OPENAI_API_KEY environment variable
3. Install yt-dlp and ffmpeg
## Usage
\`./transcriber.rb process https://www.youtube.com/watch?v=VIDEO_ID --output my_output\`
EOF
cat << EOF > .gitignore
*.gem
*.rbc
/.config
/coverage/
/InstalledFiles
/pkg/
/spec/reports/
/spec/examples.txt
/test/tmp/
/test/version_tmp/
/tmp/
/.bundle
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
.env
/output
EOF
echo "Project setup complete. Set OPENAI_API_KEY and ensure yt-dlp and ffmpeg are installed before running."
@arubis
Copy link
Author

arubis commented Oct 11, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment