From 219b93a3c9459fec905424a3112ddf0827334fb4 Mon Sep 17 00:00:00 2001 From: virtuacoplenny Date: Fri, 13 Apr 2018 13:49:24 -0700 Subject: [PATCH] fix(recording): fetch events also for available broadcasts (#2810) * fix(recording): fetch events also for available broadcasts Only "persistent" broadcasts were being fetched using the YouTube API. Fetching "all" will get persistent broadcasts and events. If events use a custom encoder then the stream key can be obtained. If google hangouts is used for the event then a stream key will not be obtainable; in those cases input empty string as the stream key. * squash: fix typos, reword comments, use object for preventing duplicate broadcasts --- .../LiveStream/StartLiveStreamDialog.web.js | 44 +++++++++++++++---- react/features/recording/googleApi.js | 2 +- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/react/features/recording/components/LiveStream/StartLiveStreamDialog.web.js b/react/features/recording/components/LiveStream/StartLiveStreamDialog.web.js index c8cae5bdc..a3b70a4d1 100644 --- a/react/features/recording/components/LiveStream/StartLiveStreamDialog.web.js +++ b/react/features/recording/components/LiveStream/StartLiveStreamDialog.web.js @@ -244,13 +244,7 @@ class StartLiveStreamDialog extends Component { }) .then(() => googleApi.requestAvailableYouTubeBroadcasts()) .then(response => { - const broadcasts = response.result.items.map(item => { - return { - title: item.snippet.title, - boundStreamID: item.contentDetails.boundStreamId, - status: item.status.lifeCycleStatus - }; - }); + const broadcasts = this._parseBroadcasts(response.result.items); this._setStateIfMounted({ broadcasts @@ -331,8 +325,11 @@ class StartLiveStreamDialog extends Component { _onYouTubeBroadcastIDSelected(boundStreamID) { return googleApi.requestLiveStreamsForYouTubeBroadcast(boundStreamID) .then(response => { - const found = response.result.items[0]; - const streamKey = found.cdn.ingestionInfo.streamName; + const broadcasts = response.result.items; + const streamName = broadcasts + && broadcasts[0] + && broadcasts[0].cdn.ingestionInfo.streamName; + const streamKey = streamName || ''; this._setStateIfMounted({ streamKey, @@ -341,6 +338,35 @@ class StartLiveStreamDialog extends Component { }); } + /** + * Takes in a list of broadcasts from the YouTube API, removes dupes, + * removes broadcasts that cannot get a stream key, and parses the + * broadcasts into flat objects. + * + * @param {Array} broadcasts - Broadcast descriptions as obtained from + * calling the YouTube API. + * @private + * @returns {Array} An array of objects describing each unique broadcast. + */ + _parseBroadcasts(broadcasts) { + const parsedBroadcasts = {}; + + for (let i = 0; i < broadcasts.length; i++) { + const broadcast = broadcasts[i]; + const boundStreamID = broadcast.contentDetails.boundStreamId; + + if (boundStreamID && !parsedBroadcasts[boundStreamID]) { + parsedBroadcasts[boundStreamID] = { + boundStreamID, + status: broadcast.status.lifeCycleStatus, + title: broadcast.snippet.title + }; + } + } + + return Object.values(parsedBroadcasts); + } + /** * Renders a React Element for authenticating with the Google web client. * diff --git a/react/features/recording/googleApi.js b/react/features/recording/googleApi.js index 92651bbbb..f26538c36 100644 --- a/react/features/recording/googleApi.js +++ b/react/features/recording/googleApi.js @@ -205,7 +205,7 @@ const googleApi = { _getURLForLiveBroadcasts() { return [ 'https://content.googleapis.com/youtube/v3/liveBroadcasts', - '?broadcastType=persistent', + '?broadcastType=all', '&mine=true&part=id%2Csnippet%2CcontentDetails%2Cstatus' ].join(''); },