According to Google's YouTube v3 API reference documentation for the properties of a video resource, there is a JSON object called liveStreamingDetails which should have the following fields:
actualStartTimeactualEndTimescheduledStartTimescheduledEndTimeconcurrentViewersactiveLiveChatIdI have prepared my objects based on this structure, but I'm getting the following exceptions thrown when I try to deserialize actual JSON snippet responses from the API for videos:
JsonSerializationException: Error converting value "none" to type 'A1ITF.API+YouTube+LiveStreamDetails'. Path 'items[0].snippet.liveBroadcastContent', line 46, position 38.ArgumentException: Could not cast or convert from System.String to A1ITF.API+YouTube+LiveStreamDetails.Looking at the JSON response from the API, I completely understand the error. Here's the JSON response I'm getting (redacted for the sake of brevity):
{
"kind": "youtube#videoListResponse",
"etag": "MR2hZ6pif1LwlWdiOvdZ_4m7vDI",
"items": [
{
"kind": "youtube#video",
"etag": "hfbATXrQ1iQB2yrckDCv-dn0iiI",
"id": "skSK9lUvqjY",
"snippet": {
"publishedAt": "2020-08-14T19:00:15Z",
"channelId": "UCZGYJFUizSax-yElQaFDp5Q",
"title": "Leia, Princess of Alderaan | The Star Wars Show Book Club",
"description": <LONG DESCRIPTION TEXT>,
"thumbnails": {<THUMBNAIL OBJECTS>},
"channelTitle": "Star Wars",
"tags": [<SEVERAL TAGS>],
"categoryId": "24",
"liveBroadcastContent": "none",
"localized": {
"title": "Leia, Princess of Alderaan | The Star Wars Show Book Club",
"description": <LONG DESCRIPTION TEXT>
},
"defaultAudioLanguage": "en-US"
}
}
],
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 1
}
}
The reason for the exception is clear: the value for the liveBroadcastContent field is a single string ("none"). It is NOT the object as defined in the documentation above. Based on the documentation, what I'm expecting
"liveBroadcastContent":
{
"actualStartTime": <ISO 8601 datetime VALUE>,
"actualEndTime": <ISO 8601 datetime VALUE>,
"scheduledStartTime": <ISO 8601 datetime VALUE>,
"scheduledEndTime": <ISO 8601 datetime VALUE>,
"concurrentViewers": <unsigned long VALUE>,
"activeLiveChatId": <string VALUE>
},
or, if there isn't any information to populate the liveBroadcastContent fields
"liveBroadcastContent":
{
"actualStartTime": null,
"actualEndTime": null,
"scheduledStartTime": null,
"scheduledEndTime": null,
"concurrentViewers": null,
"activeLiveChatId": ""
},
or even
"liveBroadcastContent": {},
or just omitting that property entirely doesn't match what I'm actually receiving
"liveBroadcastContent": "none",
I've actually been struggling to find an effective way to conditionally deserialize this element for a bit now, but can't seem to get it to simply return Nothing for what the API is returning (that's another question for another time, but I'm still researching ways to hopefully accomplish that).
My initial test was for a "regular" video, though (not an actual live stream), so I figured I'd check a known live stream video. I went into my YouTube notifications and found a couple of professional/semi-pro YouTube channels that had recent live streams and picked one to test. However, the JSON for this video was also missing a structured liveStreamingDetails object (only a value of "none"). Thinking this might be a "fluke", I checked a few other videos that were designated in my YouTube notifications as being live streams and all of them showed the exact same results.
If I change the definition of this field in my object to a simple String, everything deserializes without exception and I get a (mostly) fully populated object. However, I'd actually like to have some of this information available for my application - at least to know whether or not a video is/was a live broadcast - but "none" obviously isn't going to tell me much. So, while I work on a way to make my object correctly and conditionally deserialize this field's value (I came up with some ideas while typing this), I'm wondering if anyone knows whether or not this field is actually even implemented? Am I basically spinning my wheels trying to make something work that's already been deprecated, is this something intended as being implemented in the future, or am I just being totally dense and missing something obvious (a definite and distinct possibility)?
Based on the accepted answer, I was being totally dense. I had mistakenly guessed that the liveBroadcastContent field (in the snippet object) was the same as the liveStreamingDetails object (a part of the items collection). If I had thoroughly and accurately read the documentation, I would have seen that the former is defined as (emphasis mine):
stringIndicates if the video is an upcoming/active live broadcast. Or it's "none" if the video is not an upcoming/active live broadcast.
Valid values for this property are:
livenoneupcoming
(The reason this was showing as "none" in all of my tests is that the live broadcasts had already ended)
The latter is defined as (included in the accepted answer):
objectThe
liveStreamingDetailsobject contains metadata about a live video broadcast. The object will only be present in avideoresource if the video is an upcoming, live, or completed live broadcast.
Additionally, my API request was flawed. While I was calling the correct endpoint, I wasn't actually requesting the information needed to populate the liveStreamingDetails object. I was only requesting part=snippet when I should have been requesting part=snippet,liveStreamingDetails.
EXAMPLE API REQUEST: Prepared (not live) video
https://www.googleapis.com/youtube/v3/videos?id=skSK9lUvqjY&part=snippet,liveStreamingDetails&key={API_KEY}
RETURNS (redacted for the sake of brevity)
{
"kind": "youtube#videoListResponse",
"etag": "MR2hZ6pif1LwlWdiOvdZ_4m7vDI",
"items": [
{
"kind": "youtube#video",
"etag": "hfbATXrQ1iQB2yrckDCv-dn0iiI",
"id": "skSK9lUvqjY",
"snippet": {
"publishedAt": "2020-08-14T19:00:15Z",
"channelId": "UCZGYJFUizSax-yElQaFDp5Q",
"title": "Leia, Princess of Alderaan | The Star Wars Show Book Club",
"description": <LONG DESCRIPTION TEXT>,
"thumbnails": {<THUMBNAIL OBJECTS>},
"channelTitle": "Star Wars",
"tags": [<TAGS>],
"categoryId": "24",
"liveBroadcastContent": "none",
"localized": {
"title": "Leia, Princess of Alderaan | The Star Wars Show Book Club",
"description": <LONG DESCRIPTION TEXT>
},
"defaultAudioLanguage": "en-US"
}
}
],
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 1
}
}
EXAMPLE API REQUEST: Live Stream Broadcast
https://www.googleapis.com/youtube/v3/videos?id=RX4vy_M-NS8&part=snippet,liveStreamingDetails&key={API_KEY}
RETURNS (redacted for the sake of brevity)
{
"kind": "youtube#videoListResponse",
"etag": "Aq44bdQmbZxoLEp0SOJh4xW0PSE",
"items": [
{
"kind": "youtube#video",
"etag": "9TVc3oB01vQME2QsvEJcaRueEqc",
"id": "RX4vy_M-NS8",
"snippet": {
"publishedAt": "2020-08-20T18:50:20Z",
"channelId": "UCRTQL0CmZjHlvPy5nLZ1Gfg",
"title": "Starting a new character in Star Wars: The Old Republic [Live Stream Recorded on August 20, 2020]",
"description": <LONG DESCRIPTION TEXT>,
"thumbnails": {<THUMBNAIL OBJECTS>},
"channelTitle": "HelloGreedo",
"tags": [<TAGS>],
"categoryId": "1",
"liveBroadcastContent": "none",
"localized": {
"title": "Starting a new character in Star Wars: The Old Republic [Live Stream Recorded on August 20, 2020]",
"description": <LONG DESCRIPTION TEXT>
}
},
"liveStreamingDetails": {
"actualStartTime": "2020-08-20T17:04:45Z",
"actualEndTime": "2020-08-20T18:41:23Z"
}
}
],
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 1
}
}
After correcting my API request and adding the appropriate property to my prepared object in code, everything I wanted is coming through exactly as expected/desired.
According to the docs you have already quoted:
liveStreamingDetails (object)
The
liveStreamingDetailsobject contains metadata about a live video broadcast. The object will only be present in avideoresource if the video is an upcoming, live, or completed live broadcast.
Therefore, is very much legal that the object liveStreamingDetails to be missing from a Video resource JSON response obtained from the Videos.list API endpoint.
The liveStreamingDetails object has not been deprecated at all. Check it out yourself, on the following live stream Deutsche Welle News Livestream:
Just invoke the Videos.list endpoint on the following URL (replace $APP_KEY with your application key):
https://www.googleapis.com/youtube/v3/videos?key=$APP_KEY&id=NvqKZHpKs-g&part=contentDetails,id,liveStreamingDetails,player,recordingDetails,snippet,statistics,status,topicDetails
for to get the following JSON response text:
{
"kind": "youtube#videoListResponse",
"etag": "LmFuBTaRf4C5sL3aRpTmKefaXnw",
"items": [
{
"kind": "youtube#video",
"etag": "5nm5pG-Kto-dPRTqwcnFKQxf3UU",
"id": "NvqKZHpKs-g",
"snippet": {
"publishedAt": "2019-01-21T13:21:24Z",
"channelId": "UCknLrEdhRCp1aegoMqRaCZg",
"title": "DW News Livestream | Latest news and breaking stories",
"description": "DW News goes deep beneath the surface, providing the key stories from Europe and around the world.\n\nExciting reports and interviews from the worlds of politics, business, sports, culture and social media are presented by our DW anchors in 15-, 30- and 60-minute shows.\n\nCorrespondents on the ground and experts in the studio deliver detailed insights and analysis of issues that affect our viewers around the world. We combine our expertise on Germany and Europe with a special interest in Africa and Asia while keeping track of stories from the rest of the world.\n\nInformative, entertaining and up-to-date – DW News, connecting the dots for our viewers across the globe.\n\nDeutsche Welle is Germany’s international broadcaster. We convey a comprehensive image of Germany, report events and developments, incorporate German and other perspectives in a journalistically independent manner. By doing so we promote understanding between cultures and peoples.\n\n#dwNews #LiveNews #NewsToday",
"thumbnails": {
...
},
"channelTitle": "DW News",
"tags": [
"dw news",
"live news",
"breaking news",
"news tv",
"live tv",
"news today",
"deutsche welle",
"deutsche welle news",
"nive news tv",
"tv live news",
"daily news"
],
"categoryId": "25",
"liveBroadcastContent": "live",
"localized": {
"title": "DW News Livestream | Latest news and breaking stories",
"description": "DW News goes deep beneath the surface, providing the key stories from Europe and around the world.\n\nExciting reports and interviews from the worlds of politics, business, sports, culture and social media are presented by our DW anchors in 15-, 30- and 60-minute shows.\n\nCorrespondents on the ground and experts in the studio deliver detailed insights and analysis of issues that affect our viewers around the world. We combine our expertise on Germany and Europe with a special interest in Africa and Asia while keeping track of stories from the rest of the world.\n\nInformative, entertaining and up-to-date – DW News, connecting the dots for our viewers across the globe.\n\nDeutsche Welle is Germany’s international broadcaster. We convey a comprehensive image of Germany, report events and developments, incorporate German and other perspectives in a journalistically independent manner. By doing so we promote understanding between cultures and peoples.\n\n#dwNews #LiveNews #NewsToday"
},
"defaultAudioLanguage": "en"
},
"contentDetails": {
"duration": "P0D",
"dimension": "2d",
"definition": "sd",
"caption": "false",
"licensedContent": false,
"contentRating": {
},
"projection": "rectangular"
},
"status": {
"uploadStatus": "uploaded",
"privacyStatus": "public",
"license": "youtube",
"embeddable": true,
"publicStatsViewable": true,
"madeForKids": false
},
"statistics": {
"viewCount": "17086181",
"likeCount": "49865",
"dislikeCount": "6539",
"favoriteCount": "0",
"commentCount": "0"
},
"player": {
"embedHtml": "<iframe width=\"480\" height=\"270\" src=\"//www.youtube.com/embed/NvqKZHpKs-g\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"
},
"topicDetails": {
"relevantTopicIds": [
"/m/019_rr",
"/m/07c1v",
"/m/019_rr",
"/m/07c1v"
],
"topicCategories": [
"https://en.wikipedia.org/wiki/Lifestyle_(sociology)",
"https://en.wikipedia.org/wiki/Technology"
]
},
"recordingDetails": {
},
"liveStreamingDetails": {
"actualStartTime": "2019-01-21T13:33:28Z",
"concurrentViewers": "712"
}
}
],
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 1
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With