如何获取YouTube直播的实际视频URL?

46

有没有一种方法可以获取像这样的YouTube直播流的HLS URL https://www.youtube.com/embed/WVZpCdHq3Qg

我尝试了典型的get_video_info方法,但它们似乎无法与直播流一起使用。


你说的URL是什么?HLS URL吗? - JAL
5个回答

76
你需要从视频的清单中获取HLS m3u8播放列表文件。 有手动完成此操作的方法,但为了简单起见,我将使用youtube-dl工具获取此信息。 我将使用此直播流作为示例:https://www.youtube.com/watch?v=_Gtc-GtLlTk 首先,获取视频的格式:
➜  ~ youtube-dl --list-formats https://www.youtube.com/watch\?v\=_Gtc-GtLlTk
[youtube] _Gtc-GtLlTk: Downloading webpage
[youtube] _Gtc-GtLlTk: Downloading video info webpage
[youtube] Downloading multifeed video (_Gtc-GtLlTk, aflWCT1tYL0) - add --no-playlist to just download video _Gtc-GtLlTk
[download] Downloading playlist: Southwest Florida Eagle Cam
[youtube] playlist Southwest Florida Eagle Cam: Collected 2 video ids (downloading 2 of them)
[download] Downloading video 1 of 2
[youtube] _Gtc-GtLlTk: Downloading webpage
[youtube] _Gtc-GtLlTk: Downloading video info webpage
[youtube] _Gtc-GtLlTk: Extracting video information
[youtube] _Gtc-GtLlTk: Downloading formats manifest
[youtube] _Gtc-GtLlTk: Downloading DASH manifest
[info] Available formats for _Gtc-GtLlTk:
format code  extension  resolution note
140          m4a        audio only DASH audio  144k , m4a_dash container, mp4a.40.2@128k (48000Hz)
160          mp4        256x144    DASH video  124k , avc1.42c00b, 30fps, video only
133          mp4        426x240    DASH video  258k , avc1.4d4015, 30fps, video only
134          mp4        640x360    DASH video  646k , avc1.4d401e, 30fps, video only
135          mp4        854x480    DASH video 1171k , avc1.4d401f, 30fps, video only
136          mp4        1280x720   DASH video 2326k , avc1.4d401f, 30fps, video only
137          mp4        1920x1080  DASH video 4347k , avc1.640028, 30fps, video only
151          mp4        72p        HLS , h264, aac  @ 24k
132          mp4        240p       HLS , h264, aac  @ 48k
92           mp4        240p       HLS , h264, aac  @ 48k
93           mp4        360p       HLS , h264, aac  @128k
94           mp4        480p       HLS , h264, aac  @128k
95           mp4        720p       HLS , h264, aac  @256k
96           mp4        1080p      HLS , h264, aac  @256k (best)
[download] Downloading video 2 of 2
[youtube] aflWCT1tYL0: Downloading webpage
[youtube] aflWCT1tYL0: Downloading video info webpage
[youtube] aflWCT1tYL0: Extracting video information
[youtube] aflWCT1tYL0: Downloading formats manifest
[youtube] aflWCT1tYL0: Downloading DASH manifest
[info] Available formats for aflWCT1tYL0:
format code  extension  resolution note
140          m4a        audio only DASH audio  144k , m4a_dash container, mp4a.40.2@128k (48000Hz)
160          mp4        256x144    DASH video  124k , avc1.42c00b, 30fps, video only
133          mp4        426x240    DASH video  258k , avc1.4d4015, 30fps, video only
134          mp4        640x360    DASH video  646k , avc1.4d401e, 30fps, video only
135          mp4        854x480    DASH video 1171k , avc1.4d401f, 30fps, video only
136          mp4        1280x720   DASH video 2326k , avc1.4d401f, 30fps, video only
151          mp4        72p        HLS , h264, aac  @ 24k
132          mp4        240p       HLS , h264, aac  @ 48k
92           mp4        240p       HLS , h264, aac  @ 48k
93           mp4        360p       HLS , h264, aac  @128k
94           mp4        480p       HLS , h264, aac  @128k
95           mp4        720p       HLS , h264, aac  @256k (best)
[download] Finished downloading playlist: Southwest Florida Eagle Cam

在这种情况下,有两个视频,因为直播流包含两个摄像头。从这里开始,我们需要获取特定流的HLS URL。使用-f来传递您想观看的格式,使用-g来获取该流的URL:

➜  ~ youtube-dl -f 95 -g https://www.youtube.com/watch\?v\=_Gtc-GtLlTk
https://manifest.googlevideo.com/api/manifest/hls_playlist/id/_Gtc-GtLlTk.2/itag/95/source/yt_live_broadcast/requiressl/yes/ratebypass/yes/live/1/cmbypass/yes/gir/yes/dg_shard/X0d0Yy1HdExsVGsuMg.95/hls_chunk_host/r1---sn-ab5l6ne6.googlevideo.com/playlist_type/LIVE/gcr/us/pmbypass/yes/mm/32/mn/sn-ab5l6ne6/ms/lv/mv/m/pl/20/dover/3/sver/3/fexp/9408495,9410706,9416126,9418581,9420452,9422596,9422780,9423059,9423661,9423662,9425349,9425959,9426661,9426720,9427325,9428422,9429306/upn/xmL7zNht848/mt/1456412649/ip/64.125.177.124/ipbits/0/expire/1456434315/sparams/ip,ipbits,expire,id,itag,source,requiressl,ratebypass,live,cmbypass,gir,dg_shard,hls_chunk_host,playlist_type,gcr,pmbypass,mm,mn,ms,mv,pl/signature/7E48A727654105FF82E158154FCBA7569D52521B.1FA117183C664F00B7508DDB81274644F520C27F/key/dg_yt0/playlist/index.m3u8
https://manifest.googlevideo.com/api/manifest/hls_playlist/id/aflWCT1tYL0.2/itag/95/source/yt_live_broadcast/requiressl/yes/ratebypass/yes/live/1/cmbypass/yes/gir/yes/dg_shard/YWZsV0NUMXRZTDAuMg.95/hls_chunk_host/r13---sn-ab5l6n7y.googlevideo.com/pmbypass/yes/playlist_type/LIVE/gcr/us/mm/32/mn/sn-ab5l6n7y/ms/lv/mv/m/pl/20/dover/3/sver/3/upn/vdBkD9lrq8Q/fexp/9408495,9410706,9416126,9418581,9420452,9422596,9422780,9423059,9423661,9423662,9425349,9425959,9426661,9426720,9427325,9428422,9429306/mt/1456412649/ip/64.125.177.124/ipbits/0/expire/1456434316/sparams/ip,ipbits,expire,id,itag,source,requiressl,ratebypass,live,cmbypass,gir,dg_shard,hls_chunk_host,pmbypass,playlist_type,gcr,mm,mn,ms,mv,pl/signature/4E83CD2DB23C2331CE349CE9AFE806C8293A01ED.880FD2E253FAC8FA56FAA304C78BD1D62F9D22B4/key/dg_yt0/playlist/index.m3u8

这些是您的HLS m3u8播放列表,每个播放列表对应直播流中的一个摄像头。

如果没有youtube-dl,您的操作可能如下:

获取视频ID并向get_video_info端点发起GET请求:

HTTP GET: https://www.youtube.com/get_video_info?&video_id=_Gtc-GtLlTk&el=info&ps=default&eurl=&gl=US&hl=en

在响应中,hlsvp 的值将是指向 m3u8 HLS 播放列表的链接:

https://manifest.googlevideo.com/api/manifest/hls_variant/maudio/1/ipbits/0/key/yt6/ip/64.125.177.124/gcr/us/source/yt_live_broadcast/upn/BYS1YGuQtYI/id/_Gtc-GtLlTk.2/fexp/9416126%2C9416984%2C9417367%2C9420452%2C9422596%2C9423039%2C9423661%2C9423662%2C9423923%2C9425346%2C9427672%2C9428946%2C9429162/sparams/gcr%2Cid%2Cip%2Cipbits%2Citag%2Cmaudio%2Cplaylist_type%2Cpmbypass%2Csource%2Cexpire/sver/3/expire/1456449859/pmbypass/yes/playlist_type/LIVE/itag/0/signature/1E6874232CCAC397B601051699A03DC5A32F66D9.1CABCD9BFC87A2A886A29B86CF877077DD1AEEAA/file/index.m3u8

4
@mpgn,我了解你的感受,但从实际情况来看,追查每一个违反YouTube服务条款的人是不可能的。我曾有过这样的经历。特别是在移动设备上,看看那些使用XCDYouTubeKit等工具的人数。即使你以构建有用的东西为目的,违反YouTube的条款,YouTube也不会去追究你的责任。对于这个问题的背景,就个人使用而言,我毫不犹豫地提供这个答案。 - JAL
@JAL 谢谢您提供的信息,但是如果没有那个工具,我该如何获取这些值呢?我正在尝试从Java程序中自动化完成此操作。我正在使用这段代码,但似乎不起作用https://github.com/freecode/YouTube-Downloader/blob/master/src/YouTube.java - casolorz
1
@mntgoat 你可以查看youtube-dl源代码并尝试将其翻译成Java。我已经编辑了我的答案,提供了获取m3u8 URL所需的网络请求概述。 - JAL
3
如果我能够访问到这些位,它们就是我的。 - Carter Cole
2
嘿!我运行那个流!http://www.dickpritchettrealestate.com/eagle-feed.html。 - David McSpadden
显示剩余3条评论

12

此URL返回播放器实际的video_id

https://www.youtube.com/embed/live_stream?channel=UCkA21M22vGK9GtAvq3DvSlA

UCkA21M22vGK9GtAvq3DvSlA是您的频道ID,您可以在YouTube账户的“我的频道”链接中找到它。

或者在此处https://www.youtube.com/account_advanced


4

可以做到这一点由于问题已更新,此解决方案只能提供嵌入式URL而不是HLS URL,请查看@JAL的答案并使用资源search.list和以下参数:

* part: id
* channelId: UCURGpU4lj3dat246rysrWsw
* eventType: live
* type: video

请求:

GET https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCURGpU4lj3dat246rysrWsw&eventType=live&type=video&key={YOUR_API_KEY}

结果:

 "items": [
  {
   "kind": "youtube#searchResult",
   "etag": "\"DsOZ7qVJA4mxdTxZeNzis6uE6ck/enc3-yCp8APGcoiU_KH-mSKr4Yo\"",
   "id": {
    "kind": "youtube#video",
    "videoId": "WVZpCdHq3Qg"
   }
  },

比如获取videoID值 WVZpCdHq3Qg,将此值加入到以下URL中:

https://www.youtube.com/embed/ + videoID
https://www.youtube.com/watch?v= + videoID

1
谢谢回复,但我确定我理解了。我想要获取实际的视频URL,而不是嵌入式URL。对于非直播视频,我可以获取实际的mp4 URL。 - casolorz
3
这是观看视频的网页,我想要的是视频地址和实际视频,而不是网页本身。 - casolorz
1
下载非自己拥有的视频是被YouTube禁止的。"您不得复制、再生产、分发、传输、广播、展示、销售、授权或以其他方式利用任何内容,除非事先获得YouTube或内容各自许可方的书面同意。" - mpgn
1
@mpgn “或内容的相应许可方”是贴文中关键的一部分。您可以从YouTube或正在进行直播的人那里获得同意。这两种方式都可行。 - moeiscool
1
@mpgn 他可能不会复制、分发、传输、广播、展示、出售、许可或以其他方式利用任何内容进行其他用途。他可能只是为了私人收藏而下载它,并在没有互联网连接时不时观看。 - ScienceDiscoverer
显示剩余2条评论

1

对于那些:想在安卓上从youtube观看直播视频的外行星,请按照以下步骤操作: https://exoplayer.dev/hls.html

请阅读上述文档并在Android Studio中创建ExoPlayer。

注意: 要从youtube直播视频链接获取HLS Url: 例如一个直播链接:https://youtu.be/21X5lGlDOfg。 复制链接时常见错误:https://www.youtube.com/watch?v=FdQA-pE2luQ。 你可以看到第二个链接是指向一个可能正在进行直播但仍然是视频的链接。它不是HLS。

使用方法:只需调用convertLinkToHls()而不是初始化播放器,因为我们已经在里面调用了initializePlayer()

这里是我们发起GET请求的地方:

void convertLinkToHls(String youtubeLiveLink) {

        final String[] hlsLink = {""};

        Runnable runnableCode = () -> {
            try {
                URL url = new URL(youtubeLiveLink);
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                con.setRequestMethod("GET");

                BufferedReader in = new BufferedReader(
                        new InputStreamReader(con.getInputStream()));
                String inputLine;
                StringBuffer content = new StringBuffer();
                while ((inputLine = in.readLine()) != null) {
                    content.append(inputLine);
                }
                in.close();

                if(youtubeLiveLink.contains("m3u8")){
                    hlsLink[0] = youtubeLiveLink;
                }else{
                    hlsLink[0] = extractHlsUrl(content.toString());
                }
                con.disconnect();
            } catch (Exception e) {
                hlsLink[0] = youtubeLiveLink;
                e.printStackTrace();
                Log.d("TAG", "convertLinkToHls: " +
                        ": Reason is that the link is not a live url," +
                        "copy the link by open video then right click, copy video url from youtube.");
            }
            //extractHlsUrl(response);
        };

        Thread requestThread = new Thread(runnableCode);
        requestThread.start();

        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (!requestThread.isAlive()) {
                    // hlsLink[0]
                    runOnUiThread(() -> {
                        et_url.setText(hlsLink[0]);
                        initializePlayer();
                    });
                    timer.cancel();

                    /* Here initialize the player,
                     * make you do it in runOnUiTHread() */
                }
            }
        }, 1000, 1000);
    }


在这里,我们从GET响应中提取链接:

    private static String extractHlsUrl(String response) {

        String keyName = "hlsManifestUrl";

        if (response.contains(keyName)) {
            int index = response.indexOf(keyName);
            index = index + 17;

            int lastIndex = index;
            while (lastIndex < response.length()) {
                if ((response.charAt(lastIndex) == '8') &&
                        (response.charAt(lastIndex - 1) == 'u') &&
                        (response.charAt(lastIndex - 2) == '3') &&
                        (response.charAt(lastIndex - 3) == 'm')) {
                    break;
                }

                lastIndex++;
            }
            return response.substring(index, lastIndex + 1);
        }

        return null;
    }

在这里我们为HLS流初始化Exo播放器:

    private void initializePlayer() {

        player = new SimpleExoPlayer.Builder(this)
                .build();
        playerView.setPlayer(player);

        String tempUrl = et_url.getText().toString();

        // Create a data source factory.
        DataSource.Factory dataSourceFactory = new DefaultHttpDataSourceFactory();
        // Create a HLS media source pointing to a playlist uri.
        HlsMediaSource hlsMediaSource =
                new HlsMediaSource.Factory(dataSourceFactory)
                        .createMediaSource(MediaItem.fromUri(tempUrl));

        player.setMediaSource(hlsMediaSource);
        player.setPlayWhenReady(playWhenReady);
        player.seekTo(currentWindow, playbackPosition);
        player.prepare();
        player.play();
    }


你也可以在提取链接之前显示进度条,这通常需要300毫秒。这段代码适用于Java和Android。因为我使用了传统的方法来获取请求和后台任务的线程。
如果链接已经是m3u8格式,那么我们将直接链接到播放器,因此它适用于YouTube直播视频和任何其他m3u8链接。
这背后的概念是什么?我正在使用实时视频URL调用get请求,并在约400KB的StringBuffer响应中提取hlsManifestUrl标记。这并不是什么高深的科学。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接