- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试开发一个允许用户在 Youtube 上直播的应用程序。我已经使用范围实现了 OAuth 2.0 登录 -
googleapis.com/auth/youtube
googleapis.com/auth/youtube.force-ssl
现在显示如下:
成功登录后重定向到我的应用程序,我想使用 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 Data API 并且应该在 URL 字符串中提供 API key 和访问 token 。我也在发布代码片段。
在谷歌登录时需要添加范围和数据 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)
}
}
关于iOS Youtube 直播 API 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44567352/
我致力于收集互联网广播流文件,例如 m3u,其中包含一个流式链接 (例如 http://aska.ru-hoster.com:8053/autodj )。 我没有找到关于如何检查链接是否可用/有效的示
为了学校,我需要建立一个 HTML5 直播网站。他们有一个他们一直在使用的 Flash 流播放器,但现在他们希望它改用 HTML5。我怎样才能做到这一点?我尝试使用视频标签,但无法正常工作。下面是我的
我正在尝试使用 FFmpeg 将视频循环流式传输到 justin.tv?我已经设法循环图像序列并将其与音频中的线条组合起来: ffmpeg -loop 1 -i imageSequence%04d.j
使用 WebAudio API 播放直播流的正确方法是什么。 我正在尝试使用以下代码,但是我看到的只是正在下载 MP3,但没有播放;可能 MediaElementSource 需要一个文件,而不是连续
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 6 年前。 Improve this qu
我正在开发一个播放实时 HTTP 网络广播流(.pls、.mp3 ...)的应用程序。我可以使用 MPMusicPlayerController 播放流吗?塔克斯。 最佳答案 我认为您不能使用 MPM
好的,我一直在努力解决这个 http 直播。我只是不明白,是的,我已经阅读了所有苹果文档并观看了 wwdc 视频,但仍然非常困惑,所以请帮助想成为程序员的人!!! 你写的代码跑到服务器上了?不在 xc
我正在尝试构建一个移动应用程序,该应用程序从设备的摄像头流式传输视频并将其实时发送到服务器。此外,移动设备应该能够播放从服务器接收到的实况视频。 我正在 Flutter 中构建应用程序,但似乎无法在
我正在使用 ffmpeg sdk 在 youtube live 上流式传输实时视频 av_interleaved_write_frame(m_pAvFmtCntx, pkt); av_interlea
我在 android 上使用 ffmpeg 3.4 版本的源代码。我尝试使用它来复用音频/视频元素流作为 m3u8 输出并使用以下选项: int num = av_opt_set_from_s
我正在尝试使用静态图像和音频文件通过 ffmpeg 进行直播。像这样的ffmpeg命令 ffmpeg -re -loop 1 -f image2 -i '/tmp/11.jpg' -f lavfi -
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
我希望能够将 iPhone 摄像头的帧/视频(实时)流式传输到互联网。我在线程(streaming video FROM an iPhone)中看到可以使用AVCaptureSession的begin
我想创建一个网站,每个用户都可以创建/开始直播。 但正如我现在所看到的,我只能为我自己的帐户创建一个流。启用了 Youtube 数据 API 的那个。 key 是用代码编写的。所以我无权从某人的帐户创
我正在构建一个监控系统,它可以在白天将视频流式传输到 YouTube,但在夜间会关闭。 YouTube 直播在停止接收数据时会自动关闭流。 我可以使用 API 开始另一个流,但我想为公众保留相同的 Y
我在 YouTube 上有现场事件,我想在我的网站上播放它。我想将我的事件设为私有(private),获取它的 RTMP 广播 URL 并将其粘贴到我的网站上,在 JWPlayer 中。 那可能吗?
1- 哪一个更适合用于流媒体视频? TCP 或 UDP 套接字以及为什么? 2-直播时,音频和视频分别来自服务器,那么如何确保我显示的视频和设备上播放的音频同步? 最佳答案 我不久前编写了一个语音聊天
一直在使用 ffmpeg 通过 HLS 进行直播并通过 video.js 进行播放。它可以工作,但流开始的时间和实际开始播放的时间之间有 20 秒的延迟。 你知道为什么下面的 ffmpeg 命令不会像
除了无法解释的 Sample TV Input 应用 (https://github.com/googlesamples/androidtv-sample-inputs/),没有很多关于如何在 Liv
我真的厌倦了这个问题。如果有人在这方面帮助我,我将不胜感激。 我的一个应用被拒绝,原因是 Video streaming content over a cellular network longer
我是一名优秀的程序员,十分优秀!