2017-06-15 108 views
0

我想開發一個允許用戶在Youtube上直播的應用程序。我已經實施的OAuth 2.0登錄使用範圍 -iOS Youtube直播API錯誤

googleapis.com/auth/youtube googleapis.com/auth/youtube.force-ssl

它現在顯示是這樣的: see image 1

成功登錄後重定向到我的應用程序,我想要創建直播與API- https://www.googleapis.com/youtube/v3/liveStreams併發布數據以及。請檢查我下面的代碼片段 -

GTMSessionFetcherService *fetcherService = [[GTMSessionFetcherService alloc] init]; 
    fetcherService.authorizer = self.authorization; 
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
    [dict setValue:@{@"title":@"FS New Vod", @"description":@"hahahahah its coming now"} forKey:@"snippet"]; 
    [dict setValue:@{@"format":@"360p", @"ingestionType":@"rtmp"} forKey:@"cdn"]; 
    [dict setValue:@{@"isReusable":@"false"} forKey:@"contentDetails"]; 
    NSError *error; 
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict 
                 options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string 
                 error:&error]; 
    NSMutableURLRequest * req = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:[@"https://www.googleapis.com/youtube/v3/liveStreams?part=cdn,snippet,contentDetails&onBehalfOfContentOwner=sdfdsfds&onBehalfOfContentOwnerChannel=Ankush_FS&key=" stringByAppendingString:self.authorization.authState.lastTokenResponse.accessToken]] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; 
    req.HTTPMethod = @"POST"; 
    GTMSessionFetcher *ft = [fetcherService fetcherWithRequest:req]; 
    ft.bodyData = jsonData; 
    [ft beginFetchWithCompletionHandler:^(NSData * _Nullable data, NSError * _Nullable error) { 
     if (error) { 
      // OIDOAuthTokenErrorDomain indicates an issue with the authorization. 
      if ([error.domain isEqual:OIDOAuthTokenErrorDomain]) { 
       [self setGtmAuthorization:nil]; 
       [self logMessage:@"Authorization error during token refresh, clearing state. %@", error]; 
       // Other errors are assumed transient. 
      } else { 
       [self logMessage:@"Transient error during token refresh. %@", error]; 
      } 
      return; 
     } 
     NSError *jsonError = nil; 
     id jsonDictionaryOrArray = 
     [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError]; 

     // JSON error. 
     if (jsonError) { 
      [self logMessage:@"JSON decoding error %@", jsonError]; 
      return; 
     } 

     // Success response! 
     [self logMessage:@"Success: %@", jsonDictionaryOrArray]; 
    }]; 

但每次得到錯誤 -

Example-iOS[5413:160436] Transient error during token refresh. Error Domain=com.google.HTTPStatus Code=400 "(null)" UserInfo={data=<7b0a2022 6572726f 72223a20 7b0a2020 22657272 6f727322 3a205b0a 2020207b 0a202020 2022646f 6d61696e 223a2022 676c6f62 616c222c 0a202020 20227265 61736f6e 223a2022 70617273 65457272 6f72222c 0a202020 20226d65 73736167 65223a20 22546869 73204150 4920646f 6573206e 6f742073 7570706f 72742070 61727369 6e672066 6f726d2d 656e636f 64656420 696e7075 742e220a 2020207d 0a20205d 2c0a2020 22636f64 65223a20 3430302c 0a202022 6d657373 61676522 3a202254 68697320 41504920 646f6573 206e6f74 20737570 706f7274 20706172 73696e67 20666f72 6d2d656e 636f6465 6420696e 7075742e 220a207d 0a7d0a>} 

我在這裏做什麼錯?任何其他方式來訪問YouTube的API服務?

請幫忙!

在此先感謝!

回答

0

經過大量的研究,我得到了解決方案。我們需要調用Youtube Data API並在URL字符串中提供API密鑰和訪問令牌。我也發佈了代碼片段。 當谷歌登錄時,需要添加範圍和數據api應該爲谷歌開發者控制檯中的特定應用啓用。

@IBAction func btnYoutubeLiveDidTapped(_ sender: Any) { 
    loaderWillShow(status: true) 
    var scopes = GIDSignIn.sharedInstance().scopes 
    scopes?.append("https://www.googleapis.com/auth/youtube") 
    scopes?.append("https://www.googleapis.com/auth/youtube.force-ssl") 
    scopes?.append("https://www.googleapis.com/auth/youtube.upload") 
    scopes?.append("https://www.googleapis.com/auth/youtubepartner") 
    GIDSignIn.sharedInstance().scopes = scopes 
    GIDSignIn.sharedInstance().signIn() 
} 


func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) { 
    loaderWillShow(status: false) 
    if (error == nil) { 
     let alert = UIAlertController(title: "Broadcast Details", message: "Kindly provide us the following details.", preferredStyle: UIAlertControllerStyle.alert) 
     alert.addTextField(configurationHandler: { (tf: UITextField) in 
      tf.placeholder = "Title (required)" 
     }) 
     alert.addTextField(configurationHandler: { (tf: UITextField) in 
      tf.placeholder = "Description" 
     }) 
     let actionCancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil) 
     let actionOkay = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: { (action: UIAlertAction) in 
      if !(alert.textFields?.first?.text?.isEmpty)! { 
       DispatchQueue.main.async { 
        self.loaderWillShow(status: true) 
       } 
       var dictData = [String: Any]() 
       dictData["snippet"] = ["title": alert.textFields?.first?.text!, "description": alert.textFields?[1].text == "" ? DEFAULT_VIDEO_DESC : alert.textFields?[1].text!] 
       dictData["cdn"] = ["format": "480p", "ingestionType": "rtmp"] 
       dictData["contentDetails"] = ["isReusable": "false"] 
       let apiMngr = APIManager() 
       apiMngr.requestType = .Post 
       var url = URL(string: "https://www.googleapis.com/youtube/v3/liveStreams?part=cdn,snippet,contentDetails&key=\(GOOGLE_API_KEY)&access_token=\(signIn.currentUser.authentication.accessToken!)")! 
       apiMngr.startDataRequestWith(url: url, data: dictData, completion: { (response: Data?, error: Error?) in 
        if error == nil, let dicStream = apiMngr.getResponseDictionary() { 
         print(dicStream) 
         let formatter = DateFormatter() 
         formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.0Z" 
         dictData = [String: Any]() 
         dictData["snippet"] = ["title": (dicStream["snippet"] as! Dictionary<String, Any>)["title"] as! String, "description": (dicStream["snippet"] as! Dictionary<String, Any>)["description"] as! String, "scheduledStartTime": formatter.string(from: Date())] 
         dictData["status"] = ["privacyStatus": "public"] 
         url = URL(string: "https://www.googleapis.com/youtube/v3/liveBroadcasts?part=snippet,status&key=\(GOOGLE_API_KEY)&access_token=\(signIn.currentUser.authentication.accessToken!)")! 
         let apiMngr2 = APIManager() 
         apiMngr2.requestType = .Post 
         apiMngr2.startDataRequestWith(url: url, data: dictData, completion: { (response: Data?, error: Error?) in 
          if error == nil, let dicBroadcast = apiMngr2.getResponseDictionary() { 
           print(dicBroadcast) 
           url = URL(string: "https://www.googleapis.com/youtube/v3/liveBroadcasts/bind?part=id,snippet,contentDetails,status&id=\(dicBroadcast["id"] as! String)&streamId=\(dicStream["id"] as! String)&key=\(GOOGLE_API_KEY)&access_token=\(signIn.currentUser.authentication.accessToken!)")! 
           let apiMngr3 = APIManager() 
           apiMngr3.requestType = .Post 
           apiMngr3.startDataRequestWith(url: url, data: [:], completion: { (response: Data?, error: Error?) in 
            if error == nil, let dicBroadcastBind = apiMngr3.getResponseDictionary() { 
             print(dicBroadcastBind) 
             self.imgLiveFrom.image = UIImage(named: "YouTube.png") 
             self.streamURL = URL(string: "\((((dicStream["cdn"] as! Dictionary<String, Any>)["ingestionInfo"] as! Dictionary<String, String>)["ingestionAddress"])!)/\((((dicStream["cdn"] as! Dictionary<String, Any>)["ingestionInfo"] as! Dictionary<String, String>)["streamName"])!)") 
             self.sendStreamURLToServer() 
            } else { 
             DispatchQueue.main.async { 
              self.loaderWillShow(status: false) 
              self.showAlert(msg: ALERT_MESSAGE_PUBLISH_ERROR) 
             } 
            } 
           }) 
          } else { 
           DispatchQueue.main.async { 
            self.loaderWillShow(status: false) 
            self.showAlert(msg: ALERT_MESSAGE_PUBLISH_ERROR) 
           } 
          } 
         }) 
        } else { 
         DispatchQueue.main.async { 
          self.loaderWillShow(status: false) 
          self.showAlert(msg: ALERT_MESSAGE_PUBLISH_ERROR) 
         } 
        } 
       }) 
      } else { 
       let alert2 = UIAlertController(title: ALERT_TITLE, message: ALERT_MESSAGE_YOUTUBE_TITLE, preferredStyle: UIAlertControllerStyle.alert) 
       let actionCancel = UIAlertAction(title: "Ok", style: UIAlertActionStyle.cancel, handler: nil) 
       DispatchQueue.main.async { 
        self.present(alert2, animated: true, completion: nil) 
       } 
       alert2.addAction(actionCancel) 
      } 
     }) 
     alert.addAction(actionCancel) 
     alert.addAction(actionOkay) 
     present(alert, animated: true, completion: nil) 
    } else { 
     self.showAlert(msg: ALERT_MESSAGE_PUBLISH_ERROR) 
    } 
} 
+0

感謝此代碼片段我可以在YouTube上創建實時活動......但是我的所有活動都剛剛創建而沒有實現。 「等待用戶名」在視頻中顯示。如果你這樣做,你能幫忙嗎? – TheTiger