【问题标题】:Is the liveStreamingDetails property of a YouTube video deprecated/not implemented?YouTube 视频的 liveStreamingDetails 属性是否已弃用/未实施?
【发布时间】:2020-12-11 00:18:26
【问题描述】:

根据谷歌的YouTube v3 API reference documentation for the properties of a video resource,有一个名为liveStreamingDetails的JSON对象应该有以下字段:

  • actualStartTime
  • actualEndTime
  • scheduledStartTime
  • scheduledEndTime
  • concurrentViewers
  • activeLiveChatId

我已经根据这种结构准备了我的对象,但是当我尝试反序列化来自视频 API 的实际 JSON snippet 响应时,我收到了以下异常:

  1. JsonSerializationException: Error converting value "none" to type 'A1ITF.API+YouTube+LiveStreamDetails'. Path 'items[0].snippet.liveBroadcastContent', line 46, position 38.
  2. ArgumentException: Could not cast or convert from System.String to A1ITF.API+YouTube+LiveStreamDetails.

查看来自 API 的 JSON 响应,我完全理解错误。这是我收到的 JSON 响应(为简洁起见已编辑):

{
  "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
  }
}

异常原因很明确:liveBroadcastContent 字段的值是单个字符串 ("none")。它不是上面文档中定义的对象。根据文档,我期待

"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>
  },

或者,如果没有任何信息可以填充 liveBroadcastContent 字段

"liveBroadcastContent": 
  {
    "actualStartTime": null,
    "actualEndTime": null,
    "scheduledStartTime": null,
    "scheduledEndTime": null,
    "concurrentViewers": null,
    "activeLiveChatId": ""
  },

甚至

"liveBroadcastContent": {},

或只是完全省略该属性与我实际接收的内容不匹配接收

"liveBroadcastContent": "none",

我实际上一直在努力寻找一种有效的方法来有条件地反序列化这个元素,但似乎无法让它简单地返回 Nothing 来表示 API 返回的内容(这是另一个再次提出问题,但我仍在研究希望实现这一目标的方法)。

不过,我最初的测试是针对“常规”视频(不是实际的直播),所以我想我会检查一个已知的直播视频。我查看了我的 YouTube 通知,发现了几个专业/半专业的 YouTube 频道,它们最近有直播,并选择了一个进行测试。但是,此视频的 JSON缺少结构化的 liveStreamingDetails 对象(只有 "none" 的值)。认为这可能是“侥幸”,我检查了一些其他视频,这些视频在我的 YouTube 通知中被指定为直播,所有视频都显示了完全相同的结果。

如果我将对象中此字段的定义更改为简单的String,则所有内容都会毫无例外地反序列化,并且我得到一个(大部分)完全填充的对象。但是,我实际上喜欢为我的应用程序提供这些信息 - 至少要知道视频是否是/曾经是现场直播 - 但 "none" 显然不会告诉我很多。所以,虽然我正在努力使我的对象正确并有条件地反序列化这个字段的值(我在输入这个时想出了一些想法),我想知道是否有人知道这个字段是否真的实现了?我基本上是在旋转我的轮子,试图让已经被弃用的东西工作,这是打算在未来实施的东西,还是我只是完全密集并且错过了一些明显的东西(一个明确而明显的可能性)?


编辑(由接受的答案解决)

根据接受的答案,我 非常密集。我错误地猜测 liveBroadcastContent 字段(snippet 对象中)与 liveStreamingDetails 对象相同(items 集合的一部分)。如果我彻底准确地阅读了文档,我会看到前者被定义为(emphasis mine):

string

表明视频是否为即将到来的/活跃的直播。或者,如果视频不是即将播出/活跃直播,则为“无”。

此属性的有效值为:

  • live
  • none
  • upcoming

在我所有的测试中显示为"none"的原因是直播已经结束了

后者被定义为(包含在接受的答案中):

object

liveStreamingDetails 对象包含有关实时视频广播的元数据。如果视频是即将播出、正在直播或已完成的直播,则该对象只会出现在 video 资源中。

此外,我的 API 请求存在缺陷。当我调用正确的端点时,我实际上并没有请求填充liveStreamingDetails 对象所需的信息。当我应该请求 part=snippet,liveStreamingDetails 时,我才请求 part=snippet


示例 API 请求:准备好的(非现场)视频

https://www.googleapis.com/youtube/v3/videos?id=skSK9lUvqjY&part=snippet,liveStreamingDetails&key={API_KEY}

返回为简洁起见编辑

{
  "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
  }
}

示例 API 请求:实时流广播

https://www.googleapis.com/youtube/v3/videos?id=RX4vy_M-NS8&part=snippet,liveStreamingDetails&key={API_KEY}

返回为简洁起见编辑

{
  "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
  }
}

在更正我的 API 请求并将适当的属性添加到我在代码中准备好的对象之后,我想要的一切都完全按照预期/期望的方式完成。

【问题讨论】:

    标签: json youtube json.net youtube-data-api


    【解决方案1】:

    根据您已经引用的文档:

    liveStreamingDetails(对象)

    liveStreamingDetails 对象包含有关实时视频广播的元数据。如果视频是即将播出、正在直播或已完成的直播,则该对象只会出现在 video 资源中。

    因此,从Videos.list API 端点获得的视频资源 JSON 响应中缺少对象 liveStreamingDetails 是非常合法的。


    liveStreamingDetails 对象根本没有被弃用。自己去看看吧,在下面的直播Deutsche Welle News Livestream

    只需在以下 URL 上调用 Videos.list 端点(将 $APP_KEY 替换为您的应用程序密钥):

    https://www.googleapis.com/youtube/v3/videos?key=$APP_KEY&amp;id=NvqKZHpKs-g&amp;part=contentDetails,id,liveStreamingDetails,player,recordingDetails,snippet,statistics,status,topicDetails

    用于获取以下 JSON 响应文本:

    {
        "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
        }
    }
    

    【讨论】:

    • 是的,但这对我来说是,如果没有可用的liveStreamingDetails 信息,则该元素将根本不存在 - 或者,至少是空的,但仍然按照定义的结构。元素存在而不是预期格式的事实是我提出问题的原因。我对问题进行了编辑,以包含有关“期望与现实”的信息。
    • 我想我在自己的逻辑中发现了缺陷,而且它只是在我提交的 API 调用中。我正在使用part=snippet 并查看liveBroadcastContent 字段,期望that 是为liveStreamingDetails 定义的对象。我需要将liveBroadcastContent 字段保留为字符串,并将liveStreamingDetails 放在snippet 之外。谢谢你。这完全清除了它!
    猜你喜欢
    • 2020-01-14
    • 2012-01-18
    • 2015-07-13
    • 2013-06-28
    • 2022-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    相关资源
    最近更新 更多