2
votes

I'm trying to upload a video using youtube api, with Ruby. But I'm getting the following error:

badContent: Media type 'application/mp4' is not supported. Valid media types: [video/*, application/octet-stream]

If I check the video file is video/mp4

file --mime-type test.mp4 test.mp4: video/mp4

I'm using the code from the official documentation:

require 'rubygems'
gem 'google-api-client', '>0.7'
require 'google/apis'
require 'google/apis/youtube_v3'
require 'googleauth'
require 'googleauth/stores/file_token_store'

require 'fileutils'

# REPLACE WITH VALID REDIRECT_URI FOR YOUR CLIENT
REDIRECT_URI = 'http://localhost'
APPLICATION_NAME = 'my_app_name'

# REPLACE WITH NAME/LOCATION OF YOUR client_secrets.json FILE
CLIENT_SECRETS_PATH = 'youtbe_secret.json'

# REPLACE FINAL ARGUMENT WITH FILE WHERE CREDENTIALS WILL BE STORED
CREDENTIALS_PATH = "youtube-quickstart-ruby-credentials.yaml"


# SCOPE FOR WHICH THIS SCRIPT REQUESTS AUTHORIZATION
SCOPE = Google::Apis::YoutubeV3::AUTH_YOUTUBE_FORCE_SSL

def authorize
  FileUtils.mkdir_p(File.dirname(CREDENTIALS_PATH))

  client_id = Google::Auth::ClientId.from_file(CLIENT_SECRETS_PATH)
  token_store = Google::Auth::Stores::FileTokenStore.new(file: CREDENTIALS_PATH)
  authorizer = Google::Auth::UserAuthorizer.new(
    client_id, SCOPE, token_store)
  user_id = 'default'
  credentials = authorizer.get_credentials(user_id)
  if credentials.nil?
    url = authorizer.get_authorization_url(base_url: REDIRECT_URI)
    puts "Open the following URL in the browser and enter the " +
         "resulting code after authorization"
    puts url
    code = gets
    credentials = authorizer.get_and_store_credentials_from_code(
      user_id: user_id, code: code, base_url: REDIRECT_URI)
  end
  credentials
end

# Initialize the API
service = Google::Apis::YoutubeV3::YouTubeService.new
service.client_options.application_name = APPLICATION_NAME
service.authorization = authorize

# Print response object as JSON
def print_results(response)
  puts response.to_json
end

# Build a resource based on a list of properties given as key-value pairs.
def create_resource(properties)
  resource = {}
  properties.each do |prop, value|
    ref = resource
    prop_array = prop.to_s.split(".")
    for p in 0..(prop_array.size - 1)
      is_array = false
      key = prop_array[p]
      # For properties that have array values, convert a name like
      # "snippet.tags[]" to snippet.tags, but set a flag to handle
      # the value as an array.
      if key[-2,2] == "[]"
        key = key[0...-2]
        is_array = true
      end
      if p == (prop_array.size - 1)
        if is_array
          if value == ""
            ref[key.to_sym] = []
          else
            ref[key.to_sym] = value.split(",")
          end
        elsif value != ""
          ref[key.to_sym] = value
        end
      elsif ref.include?(key.to_sym)
        ref = ref[key.to_sym]
      else
        ref[key.to_sym] = {}
        ref = ref[key.to_sym]
      end
    end
  end
  return resource
end

### END BOILERPLATE CODE

# Sample ruby code for videos.insert

def videos_insert(service, properties, part, **params)
  resource = create_resource(properties) # See full sample for function
  params = params.delete_if { |p, v| v == ''}
  response = service.insert_video(part, resource, params)
end

videos_insert(service, {'snippet.category_id': '22',
   'snippet.default_language': '',
   'snippet.description': 'Description of uploaded video.',
   'snippet.tags[]': '',
   'snippet.title': 'Test video upload',
   'status.embeddable': '',
   'status.license': '',
   'status.privacy_status': 'private',
   'status.public_stats_viewable': ''}, 'snippet,status', upload_source: 'test.mp4')

The full stacktrace is:

ruby upload_video.rb /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/google-api-client-0.20.1/lib/google/apis/core/http_command.rb:218:in check_status': badContent: Media type 'application/mp4' is not supported. Valid media types: [video/*, application/octet-stream] (Google::Apis::ClientError) from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/google-api-client-0.20.1/lib/google/apis/core/api_command.rb:116:in check_status' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/google-api-client-0.20.1/lib/google/apis/core/http_command.rb:183:in process_response' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/google-api-client-0.20.1/lib/google/apis/core/upload.rb:170:in process_response' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/google-api-client-0.20.1/lib/google/apis/core/upload.rb:246:in execute_once' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/google-api-client-0.20.1/lib/google/apis/core/http_command.rb:104:in block (2 levels) in execute' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/retriable-3.1.1/lib/retriable.rb:61:in block in retriable' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/retriable-3.1.1/lib/retriable.rb:57:in times' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/retriable-3.1.1/lib/retriable.rb:57:in retriable' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/google-api-client-0.20.1/lib/google/apis/core/http_command.rb:101:in block in execute' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/retriable-3.1.1/lib/retriable.rb:61:in block in retriable' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/retriable-3.1.1/lib/retriable.rb:57:in times' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/retriable-3.1.1/lib/retriable.rb:57:in retriable' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/google-api-client-0.20.1/lib/google/apis/core/http_command.rb:93:in execute' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/google-api-client-0.20.1/lib/google/apis/core/base_service.rb:360:in execute_or_queue_command' from /home/myuser/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/google-api-client-0.20.1/generated/google/apis/youtube_v3/service.rb:4131:ininsert_video' from upload_video.rb:104:in videos_insert' from upload_video.rb:107:in'

1
Have you tried using the Ruby client library to help you upload the videos? Could you also try adding your code for uploading. - Mr.Rebot
Yes, that's what I'm using. I'm using the demo code. I've added it to the question. - Mateu

1 Answers

2
votes

According to code in https://github.com/google/google-api-ruby-client/blob/b66a54c2de3da7e5951d52d9fc8aad5b313fd7e5/generated/google/apis/youtube_v3/service.rb#L4110 You can set content_type for current upload

service.insert_video(part, resource, content_type: 'video/mp4', params)