gpt4 book ai didi

ios - 使用 REST API 将视频上传到 Youtube,无需 iOS SDK

转载 作者:行者123 更新时间:2023-11-30 12:13:01 25 4
gpt4 key购买 nike

还是个菜鸟,请多多包涵。我正在将 SWIFT 3 和 V3 YouTube 数据 API 与 REST 结合使用。我可以提取我的视频列表,这样我的连接和授权就可以正常工作。

我似乎不知道如何上传。我发现了一篇与我的非常相似的旧帖子( Setting snippet data for youtube upload via REST API using Swift )。

我很困惑他们从哪里获取 token 变量以及如何将其传递到这个函数中。另外,不知道如何设置帖子之前的上传变量。如有任何帮助,我们将不胜感激!

func uploadVideo(token: String, callback: @escaping (Bool) -> Void){

let headers = ["Authorization": "Bearer \(token)"]

let path = Bundle.main.path(forResource: "intro", ofType: "mov")
let videodata: NSData = NSData.dataWithContentsOfMappedFile(path!)! as! NSData
upload(
.POST,
"https://www.googleapis.com/upload/youtube/v3/videos?part=snippet",
headers: headers,
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(data:"{'snippet':{'title' : 'TITLE_TEXT', 'description': 'DESCRIPTION_TEXT'}}".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"snippet", mimeType: "application/json")
multipartFormData.appendBodyPart(data: videodata, name: "intro", fileName: "intro.mov", mimeType: "application/octet-stream")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { request, response, error in
print(response)
callback(true)
}
case .Failure(_):
callback(false)
}
})
}

最佳答案

更新了代码 https://github.com/mfriedl89/Developer5/blob/master/Conari/Conari/ 。它主要只是一个 poc,需要重构(例如:使用 Codable 进行 JSON 解析而不是强制解包)。正确的 OAuth2 流程应使用 SFSafariViewController/SFAuthenticationSession(取决于目标 iOS 版本)或 Google SignIn

来实现
import Foundation

class YoutubeTokenProvider {

// TODO: Store token, evaluate ttl, retry request if needed
static func getAccessToken(callback: @escaping (String?) -> Void){

/* Remark (Security)
Storing the data inside here is not secure, but still better than requesting it from a custom request.
Two possibilities:
1. Storing all data here
2. Storing all data on an external server and only requesting the access token from this server
Option 1 was chosen based on the assumption that decompiling the app should be more difficult than just
monitoring the request and getting the access token (which allows the attacker to do anything with our
YouTube account). The disadvantage is that an attacker gets everything after a successful decompilation
and not only the access token.
*/

let client_secret = "..."
let grant_type = "refresh_token"
let refresh_token = "..."
let client_id = "..."

var request = URLRequest(url: URL(string: "https://accounts.google.com/o/oauth2/token")!)
request.httpMethod = "POST"
let postString = "client_secret=" + client_secret +
"&grant_type=" + grant_type +
"&refresh_token=" + refresh_token +
"&client_id=" + client_id
request.httpBody = postString.data(using: .utf8)

URLSession.shared.dataTask(with: request, completionHandler: {data, response, error in
guard let data = data, error == nil else {
callback(nil)
return
}

if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
callback(nil)
return
}

do {
let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! YouTubeManager.JSON
let accessToken = jsonData["access_token"]! as? String
callback(accessToken)
} catch {
callback(nil)
}
return
}).resume()
}
}


import Foundation

struct YoutubeVideo {
let title, thumbnailUrl, videoId: String
}


import Foundation
import Alamofire

/// This file will act as our YouTube manager.
class YouTubeManager {

typealias JSON = [String:AnyObject]
typealias SearchByTitleCallback = (_ response: [YoutubeVideo], _ success:Bool, _ message:String) -> Void
typealias PostVideoCallback = (String, Bool) -> Void

/** Singletone instance. */
static let sharedManager = YouTubeManager()

let apiKey = "..."
let channelID = "..."
let searchApiUrl = "https://www.googleapis.com/youtube/v3/search"
let identifier = "videoID: "


func parseIdentifier(input: String) -> String? {
let seperator = "videoID: "

if input.contains(self.identifier) {
let videoID = input.components(separatedBy: seperator)
return videoID.last
}

return nil
}

func searchVideoByTitle(title: String, completionHandler: @escaping SearchByTitleCallback) -> Void {
let eTitle = title.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
let urlString = searchApiUrl + "?part=snippet&q=" + eTitle + "&type=video&key=" + apiKey

let targetURL = URL(string: urlString)!
var returnArray = [YoutubeVideo]()

let task = URLSession.shared.dataTask(with: targetURL) { (data, response, error) in
guard error == nil else {
completionHandler(returnArray, false, "error = \(error!)")
return
}
guard let data = data else {
completionHandler(returnArray, false, "error = data is nil")
return
}

if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
completionHandler(returnArray, false, "response = \(response!)")
return
}

do {
let resultsDict = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! JSON

let items = resultsDict["items"] as! [JSON]
returnArray = items.map { item in
let snippetDict = item["snippet"] as! JSON
let title = snippetDict["title"] as! String
let thumbnail = ((snippetDict["thumbnails"] as! JSON)["default"] as! JSON)["url"] as! String
let videoid = (item["id"] as! JSON)["videoId"] as! String

return YoutubeVideo(title: title, thumbnailUrl: thumbnail, videoId: videoid)
}
completionHandler(returnArray, true, "")

} catch {
completionHandler(returnArray, false, "error serializing JSON: \(error)")
}
}
task.resume()
}

func postVideoToYouTube(uploadUrl: String, videoData: Data, title: String, callback: @escaping PostVideoCallback){

YoutubeTokenProvider.getAccessToken { (accessToken) in
guard let accessToken = accessToken
else { return }

let headers: HTTPHeaders = ["Authorization": "Bearer \(accessToken)"]

Alamofire.upload(
multipartFormData: { multipartFormData in
let metadata = "{'snippet':{'title' : '\(title)', 'description': 'This video was uploaded using Mr Tutor.'}}".data(using: .utf8, allowLossyConversion: false)!
multipartFormData.append(metadata, withName: "snippet", mimeType: "application/json")
multipartFormData.append(videoData, withName: "video", fileName: "sample.mp4", mimeType: "application/octet-stream")
},
to: "https://www.googleapis.com/upload/youtube/v3/videos?part=snippet",
headers: headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in

do {
let jsonData = try JSONSerialization.jsonObject(with: response.data!, options: .allowFragments) as! JSON

let videoID = jsonData["id"] as! String
let identifierFinal = self.identifier + videoID
callback(identifierFinal, true)
} catch {
print("error serializing JSON: \(error)")
callback("", false)
}

print("Success")
}
case .failure(_):
print("Failure")
callback("", false)
}
})
}

}

}

关于ios - 使用 REST API 将视频上传到 Youtube,无需 iOS SDK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45800480/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com