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)