Class: VideoProcessing::TranscriptProcessor
- Inherits:
-
Object
- Object
- VideoProcessing::TranscriptProcessor
- Defined in:
- app/services/video_processing/transcript_processor.rb
Overview
Service object for writing transcript and SEO data back to a Video record
from an AssemblyAI transcription result, and for managing the audio
extraction upload lifecycle.
Extracted from Video to move the flog-158 update_transcript_data
orchestration (conditional field updates across transcript, SEO metadata,
structured JSON, and duration) out of the model. Pure read accessors that
read transcript / structured_transcript_json stay on Video.
All methods return a Result struct following the service-architecture
convention — never a bare boolean, hash, or record.
Defined Under Namespace
Classes: Result
Instance Method Summary collapse
-
#create_audio_extraction_upload(audio_file_path) ⇒ Result
Create an audio extraction upload for the video, replacing any existing one.
-
#initialize(video) ⇒ TranscriptProcessor
constructor
Initialize the transcript processor.
-
#update_transcript_data(result) ⇒ Result
Update the video's transcript, SEO metadata, structured transcript JSON, and duration from an AssemblyAI result hash.
Constructor Details
#initialize(video) ⇒ TranscriptProcessor
Initialize the transcript processor.
47 48 49 |
# File 'app/services/video_processing/transcript_processor.rb', line 47 def initialize(video) @video = video end |
Instance Method Details
#create_audio_extraction_upload(audio_file_path) ⇒ Result
Create an audio extraction upload for the video, replacing any existing
one. Used by the transcription pipeline to store an MP3 extract.
Creates the new upload first so a failure doesn't leave the video
with no audio extraction.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'app/services/video_processing/transcript_processor.rb', line 98 def create_audio_extraction_upload(audio_file_path) old_upload = @video.audio_extraction_upload new_upload = Upload.uploadify( audio_file_path, 'audio_extraction', @video, "#{@video.title.parameterize}-audio.mp3" ) old_upload&.destroy Result.new(success: true, upload: new_upload) rescue StandardError => e Result.new(success: false, upload: nil, error: e.) end |
#update_transcript_data(result) ⇒ Result
Update the video's transcript, SEO metadata, structured transcript JSON,
and duration from an AssemblyAI result hash. Only fills in fields that
are blank on the video — existing values are preserved.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'app/services/video_processing/transcript_processor.rb', line 60 def update_transcript_data(result) Rails.logger.info "Updating transcript data with: #{result.keys}" update_hash = {} update_hash[:transcript] = result[:transcript] if result[:transcript].present? update_hash[:assemblyai_transcript_id] = result[:assemblyai_transcript_id] if result[:assemblyai_transcript_id].present? update_hash[:structured_transcript_json] = result[:structured_transcript_json] if result[:structured_transcript_json].present? && !@video.has_structured_transcript_json? if result[:seo_content].present? seo_content = result[:seo_content] update_hash[:meta_title] = seo_content['meta_title'] if @video..blank? && seo_content['meta_title'].present? update_hash[:meta_description] = seo_content['meta_description'] if @video..blank? && seo_content['meta_description'].present? update_hash[:expanded_description] = seo_content['expanded_description'] if @video..blank? && seo_content['expanded_description'].present? else Rails.logger.warn 'No SEO content found in result' end update_hash[:duration_in_seconds] = result[:duration_in_seconds] if @video.duration_in_seconds.blank? && result[:duration_in_seconds].present? if update_hash.any? @video.update!(update_hash) Rails.logger.info "Video updated successfully with: #{update_hash.keys}" Result.new(success: true, updated_attributes: update_hash.keys) else Rails.logger.info 'No updates needed' Result.new(success: true, updated_attributes: []) end rescue StandardError => e Result.new(success: false, updated_attributes: [], error: e.) end |