Class: YouTube::CaptionService

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

Overview

Pushes VTT captions from a Video's structured_transcript_json to YouTube.

Supports:

  • English polished captions (vtt_polished)
  • Translated captions for all available locales (vtt_fr_ca, vtt_es_mx, etc.)

Existing YouTube caption tracks for the same language are replaced (delete + insert).

Constant Summary collapse

LOCALE_TO_YOUTUBE_LANG =
{
  'en' => 'en',
  'fr-CA' => 'fr',
  'es-MX' => 'es',
  'pl' => 'pl',
  'de' => 'de',
  'pt-BR' => 'pt'
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(account: nil, client: nil) ⇒ CaptionService

Returns a new instance of CaptionService.



24
25
26
27
# File 'app/services/youtube/caption_service.rb', line 24

def initialize(account: nil, client: nil)
  @client = client || YouTube::ApiClient.new(account: )
  @logger = Rails.logger
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



22
23
24
# File 'app/services/youtube/caption_service.rb', line 22

def client
  @client
end

#loggerObject (readonly)

Returns the value of attribute logger.



22
23
24
# File 'app/services/youtube/caption_service.rb', line 22

def logger
  @logger
end

Instance Method Details

#push_all_captions(video) ⇒ Hash

Push all available captions (English + translations) to YouTube.

Parameters:

  • video (Video)

    must have youtube_id and structured_transcript_json

Returns:

  • (Hash)

    { uploaded: count, errors: count }



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'app/services/youtube/caption_service.rb', line 32

def push_all_captions(video)
  validate!(video)

  stats = { uploaded: 0, errors: 0 }
  existing_captions = @client.list_captions(video.youtube_id)

  if video.has_polished_vtt?
    push_caption(video, 'en', video.vtt_polished_data, existing_captions, stats)
  end

  video.available_translated_vtt_locales.each do |locale|
    vtt_data = video.vtt_translated_data(locale)
    next if vtt_data.blank?

    push_caption(video, locale, vtt_data, existing_captions, stats)
  end

  video.update_columns(youtube_caption_synced_at: Time.current) if stats[:uploaded] > 0
  stats
end

#push_caption_for_locale(video, locale) ⇒ Boolean

Push captions for a single locale.

Parameters:

  • video (Video)
  • locale (String)

    e.g. 'en', 'fr-CA'

Returns:

  • (Boolean)

    true on success

Raises:

  • (ArgumentError)


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/services/youtube/caption_service.rb', line 57

def push_caption_for_locale(video, locale)
  validate!(video)

  vtt_data = if locale == 'en'
               video.vtt_polished_data
             else
               video.vtt_translated_data(locale)
             end

  raise ArgumentError, "No VTT data for locale #{locale}" if vtt_data.blank?

  existing_captions = @client.list_captions(video.youtube_id)
  stats = { uploaded: 0, errors: 0 }
  push_caption(video, locale, vtt_data, existing_captions, stats)

  video.update_columns(youtube_caption_synced_at: Time.current) if stats[:uploaded] > 0
  stats[:uploaded] > 0
end