Class: YouTube::UploadService

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

Overview

Uploads a Video to YouTube from Cloudflare Stream or local Dragonfly attachment.

Downloads the MP4 to a temp file, then uploads via the YouTube Data API.
Handles both Cloudflare-hosted and locally-hosted videos.

Constant Summary collapse

DESCRIPTION_MAX_CHARS =

YouTube Data API limit on snippet.description length (chars).

5000

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of UploadService.



18
19
20
21
# File 'app/services/youtube/upload_service.rb', line 18

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.



16
17
18
# File 'app/services/youtube/upload_service.rb', line 16

def client
  @client
end

#loggerObject (readonly)

Returns the value of attribute logger.



16
17
18
# File 'app/services/youtube/upload_service.rb', line 16

def logger
  @logger
end

Instance Method Details

#push_metadata(video) ⇒ Object

Push current Heatwave metadata (title, description, AI disclosure, tags,
category) to an existing YouTube video. Does NOT touch privacy status —
that's controlled in Studio. Returns the updated Google::Apis video.

Raises:

  • (ArgumentError)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'app/services/youtube/upload_service.rb', line 41

def (video)
  raise ArgumentError, 'Video is not linked to a YouTube ID' if video.youtube_id.blank?

   = (video, video.youtube_privacy_status.presence || 'private')

  result = @client.update_video(
    video.youtube_id,
    snippet_attrs: {
      title: [:title],
      description: [:description],
      tags: [:tags],
      category_id: [:category_id]
    },
    status_attrs: {
      contains_synthetic_media: [:contains_synthetic_media]
    }
  )

  video.update_columns(youtube_synced_at: Time.current)
  result
end

#upload(video, privacy_status: 'private') ⇒ Video

Upload a video to YouTube.

Parameters:

  • video (Video)

    the local Video record

  • privacy_status (String) (defaults to: 'private')

    'public', 'unlisted', or 'private'

Returns:

  • (Video)

    the updated video with youtube_id set



27
28
29
30
31
32
33
34
35
36
# File 'app/services/youtube/upload_service.rb', line 27

def upload(video, privacy_status: 'private')
  validate_uploadable!(video)

  video.update_columns(youtube_upload_status: 'uploading', youtube_upload_error: nil)

  download_and_upload(video, privacy_status)
rescue StandardError => e
  video.update_columns(youtube_upload_status: 'failed', youtube_upload_error: "#{e.class}: #{e.message}")
  raise
end