Class: VideoPosterExtractionService

Inherits:
Object
  • Object
show all
Defined in:
app/services/video_poster_extraction_service.rb

Overview

Service object: video poster extraction service.

Defined Under Namespace

Classes: ExtractionError

Constant Summary collapse

JPEG_MAGIC_BYTES =

Jpeg magic bytes.

"\xFF\xD8\xFF".b.freeze
PNG_MAGIC_BYTES =

Png magic bytes.

"\x89PNG".b.freeze
MIN_IMAGE_SIZE =

1 KB — anything smaller is likely an error page

1024

Instance Method Summary collapse

Constructor Details

#initialize(video, timestamp_seconds = 10.0, target_attribute: :poster_image_id) ⇒ VideoPosterExtractionService

Returns a new instance of VideoPosterExtractionService.

Parameters:

  • target_attribute (Symbol) (defaults to: :poster_image_id)

    which FK on the video to assign the new
    Image to. Defaults to :poster_image_id (the original poster flow). Pass
    :youtube_thumbnail_image_id from the YouTube options page so the same
    pipeline can write the per-video YouTube thumbnail without disturbing
    the main poster.



23
24
25
26
27
28
29
30
31
32
33
# File 'app/services/video_poster_extraction_service.rb', line 23

def initialize(video, timestamp_seconds = 10.0, target_attribute: :poster_image_id)
  @video = video
  @target_attribute = target_attribute
  @timestamp_seconds = if timestamp_seconds
                         timestamp_seconds
                       elsif video.poster_offset.present?
                         video.poster_offset.to_i / 1000.0
                       else
                         10.0
                       end
end

Instance Method Details

#extract_posterObject

Raises ExtractionError with a descriptive message on failure so callers
(and AppSignal) see the actual root cause instead of a bare false.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'app/services/video_poster_extraction_service.rb', line 37

def extract_poster
  Rails.logger.info "Starting poster extraction for video #{@video.id} (#{@video.title}) at timestamp #{@timestamp_seconds} seconds"

  if @video.cloudflare_uid.present?
    extract_cloudflare_poster
  elsif @video.attachment_uid.present?
    extract_self_hosted_poster
  else
    raise ExtractionError, "Video #{@video.id} has no valid source (neither Cloudflare UID nor attachment UID)"
  end

  Rails.logger.info "Successfully extracted poster for video #{@video.id}"
  true
end