【问题标题】:YouTube Data API v3 update_video fails with ArgumentErrorYouTube 数据 API v3 update_video 失败并出现 ArgumentError
【发布时间】:2022-08-19 03:43:10
【问题描述】:

问题

使用 google-apis-youtube_v3 gem,我可以上传视频、删除视频、插入字幕、删除字幕并设置缩略图。唯一由于某种原因不起作用的是update_video 调用,它总是返回错误。

环境

  • 操作系统:MacOS 11.5.2
  • Ruby 版本:2.7.6
  • Gem 名称和版本:google-apis-youtube_v3-0.22.0

重现步骤

  1. 按照method documentation 中的说明,实例化服务对象并调用update_video 方法,其中part = \'id,sn-p,status\' 和指定视频ID、sn-p 和状态的视频对象。

    代码示例

    require \'googleauth\'
    require \'googleauth/stores/file_token_store\'
    require \'google-apis-youtube_v3\'
    
    REDIRECT_URI = \'http://localhost\'
    APPLICATION_NAME = \'...\'
    API_KEY = \'...\'
    
    SCOPE = Google::Apis::YoutubeV3::AUTH_YOUTUBE_FORCE_SSL
    
    def authorize
      client_id = Google::Auth::ClientId.from_file(\'secrets/client_secret.json\')
      token_store = Google::Auth::Stores::FileTokenStore.new(file: \"secrets/youtube-creds.yml\")
      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
    
    def get_service
      service = Google::Apis::YoutubeV3::YouTubeService.new
      service.key = API_KEY
      service.client_options.application_name = APPLICATION_NAME
      service.authorization = authorize
      service
    end
    
    o = {
      \"id\": \'XYZ123\',
      \"snippet\": {
        \"category_id\": \"27\",
        \"default_language\": \"en\",
        \"description\": \"Testing updating description and title.\",
        \"tags\": [
          \"tag1\",
          \"tag2\",
          \"tag3\"
        ],
        \"title\": \"Test video upload using Ruby SDK\"
      },
      \"status\": {
        \"privacy_status\": \"private\"
      }
    }
    resp = s.update_video(\'id,snippet,status\', o)
    

    结果

    ArgumentError (unknown keywords: :id, :snippet, :status)

    请注意,视频对象与最初用于创建视频的对象几乎相同。除了视频标题和描述的细微修改之外,唯一的变化是添加了id 属性来标识视频。

  • 据我从您链接的方法文档中可以看出,update_video 的第二个参数是Google::Apis::YoutubeV3::Video 对象,但您传入的是解释器正在读取的 ruby​​ 哈希作为关键字参数。
  • 非常感谢!我永远不会抓住那个。 update_video 方法将使用普通哈希,但由于它恰好是方法调用中的最后一个参数,Ruby 确实将其视为要单独传递给方法的关键字参数的集合,而不是单个值作为video_object 参数传递。如果您发布您的评论作为答案,我将很乐意将其标记为正确。

标签: ruby youtube-data-api google-api-ruby-client


【解决方案1】:

Jim Gay 在他的评论中解决了这个问题。正如我所想,ArgumentError 不是 YouTube API gem 抛出的。这是在调用 API 方法之前引发的 Ruby 异常。

问题是该方法的第二个参数默认为 nil,因此如果您将视频对象作为普通哈希传入,并且它恰好是方法调用中的第二个和最后一个参数,Ruby 会将其解释为关键字(命名)参数的集合,而不是作为要传递给第二个参数的单个值。所以:id:snippet:status 不被识别为有效参数,因为方法签名没有声明它们。

这不是insert_video API 调用的问题,因为除了视频对象之外,您很可能必须将视频文件的位置作为命名参数之一传递。

正如 Jim 所指出的,您可以构造一个 Google::Apis::YoutubeV3::Video 对象并将其作为第二个/最后一个参数传入,没有歧义。唯一的不便之处是您还必须在视频对象内构建视频 sn-p 和状态对象。

另一种可能性是首先使用list_videos API 调用从YouTube 获取视频对象,根据需要编辑值,然后将其传递给update_video

不过,最简单的方法是将视频对象作为普通哈希传递,但还要传递一个实际的命名参数,让 Ruby 知道第二个参数在传递之前不应该被解包。例如:

resp = s.update_video('id,snippet,status', o, options: nil)

【讨论】:

    猜你喜欢
    • 2016-05-03
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 2013-08-25
    • 2013-10-08
    • 2016-06-26
    • 1970-01-01
    • 2016-05-10
    相关资源
    最近更新 更多