Java 如何在 Android 的 ExoPlayer 中播放 Youtube 视频?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29607104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:17:50  来源:igfitidea点击:

How to play Youtube video in ExoPlayer in Android?

javaandroidyoutubeexoplayer

提问by Amit Prajapati

I am trying to play youtube video in exoplayer but here is some confusion I don't know what is DASH url, I have only real youtube url like "https://www.youtube.com/watch?v=v1uyQZNg2vE" , I have no idea how to generate dash url form real url.

我正在尝试在 exoplayer 中播放 youtube 视频,但这里有些混乱我不知道什么是 DASH 网址,我只有真正的 youtube 网址,例如“ https://www.youtube.com/watch?v=v1uyQZNg2vE”,我不知道如何从真实 url 生成破折号 url。

Dash Url:

破折号网址:

new Sample("Google Glass",
        "http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?"
        + "as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,as&ip=0.0.0.0&"
        + "ipbits=0&expire=19000000000&signature=255F6B3C07C753C88708C07EA31B7A1A10703C8D."
        + "2D6A28B21F921D0B245CDCF36F7EB54A2B5ABFC2&key=ik0", DemoUtil.TYPE_DASH),

Real Url :

真实网址:

 https://www.youtube.com/watch?v=v1uyQZNg2vE

回答by GAG'sB

You will have to get the HTTP response from the youtube URL (in your case real URL) and then search for the section "url_encoded_fmt_stream_map". In that section you will get a URI which needs to be decoded twice to get the DASH URL you are looking for.

您必须从 youtube 网址(在您的情况下为真实网址)获取 HTTP 响应,然后搜索“url_encoded_fmt_stream_map”部分。在该部分中,您将获得一个 URI,该 URI 需要解码两次才能获得您要查找的 DASH URL。

回答by Karim Abdell Salam

I had the same issue but i finally found the simplest solution and its working so good

我遇到了同样的问题,但我终于找到了最简单的解决方案,而且效果很好

  1. First you need to call this url..

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

  1. 首先你需要调用这个网址..

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

and don't forget to change the last id with the target one.

并且不要忘记使用目标 ID 更改最后一个 ID。

  1. now you will get notice to download a file called get_video_info with no extesion.
  2. try to open this file using notepad and so.
  3. Now you have the right data but you can't read it because its encoded You need HTML decoder to reed this data use this one: http://meyerweb.com/eric/tools/dencoder/
  1. 现在你会收到通知下载一个名为 get_video_info 的文件,没有扩展。
  2. 尝试使用记事本等打开此文件。
  3. 现在您拥有正确的数据,但您无法读取它,因为它已编码您需要 HTML 解码器来读取此数据,请使用此数据:http: //meyerweb.com/eric/tools/dencoder/

-just paste your data and press decode a several times to ensure it decoded well

- 只需粘贴您的数据并按解码几次以确保其解码良好

finally search for a key called dashmpd

最后搜索一个叫做 dashmpd 的键

and enjoy ur URL

并享受您的网址

Or use this Simple Solution

或者使用这个简单的解决方案

private void extractYoutubeUrl() {
    @SuppressLint("StaticFieldLeak") YouTubeExtractor mExtractor = new YouTubeExtractor(this) {
        @Override
        protected void onExtractionComplete(SparseArray<YtFile> sparseArray, VideoMeta videoMeta) {
            if (sparseArray != null) {
                playVideo(sparseArray.get(17).getUrl());
            }
        }
    };
    mExtractor.extract(mYoutubeLink, true, true);


implementation 'com.github.HaarigerHarald:android-youtubeExtractor:v1.7.0'

回答by MARK002-MAB

I've written a class that retrieves actual YouTube video streaming URL for format like DASH and HLS using http://www.youtube.com/get_video_info?&video_id=[video_id]&el=info&ps=default&eurl=&gl=US&hl=enurl with video ID as described by Karim Abdell Salam. I have also tested the URL in an app that uses ExoPlayerand it works:

我编写了一个类,它使用http://www.youtube.com/get_video_info?&video_id=[video_id]&el=info&ps=default&eurl=&gl=US&hl=enurl检索 DASH 和 HLS 等格式的实际 YouTube 视频流 URL Karim Abdell Salam描述的视频 ID 。我还在一个使用ExoPlayer的应用程序中测试了 URL ,它可以工作:

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Map;
import java.util.TreeMap;

/**
 * Represents youtube video information retriever.
 */
public class YouTubeVideoInfoRetriever
{
    private static final String URL_YOUTUBE_GET_VIDEO_INFO = "http://www.youtube.com/get_video_info?&video_id=";

    public static final String KEY_DASH_VIDEO = "dashmpd";
    public static final String KEY_HLS_VIDEO = "hlsvp";

    private TreeMap<String, String> kvpList = new TreeMap<>();

    public void retrieve(String videoId) throws IOException
    {
        String targetUrl = URL_YOUTUBE_GET_VIDEO_INFO + videoId+"&el=info&ps=default&eurl=&gl=US&hl=en";
        SimpleHttpClient client = new SimpleHttpClient();
        String output = client.execute(targetUrl, SimpleHttpClient.HTTP_GET, SimpleHttpClient.DEFAULT_TIMEOUT);
        parse(output);
    }

    public String getInfo(String key)
    {
        return kvpList.get(key);
    }

    public void printAll()
    {
        System.out.println("TOTAL VARIABLES=" + kvpList.size());

        for(Map.Entry<String, String> entry : kvpList.entrySet())
        {
            System.out.print( "" + entry.getKey() + "=");
            System.out.println("" + entry.getValue() + "");
        }
    }

    private void parse(String data) throws UnsupportedEncodingException
    {
        String[] splits = data.split("&");
        String kvpStr = "";

        if(splits.length < 1)
        {
            return;
        }

        kvpList.clear();

        for(int i = 0; i < splits.length; ++i)
        {
            kvpStr = splits[i];

            try
            {
                // Data is encoded multiple times
                kvpStr = URLDecoder.decode(kvpStr, SimpleHttpClient.ENCODING_UTF_8);
                kvpStr = URLDecoder.decode(kvpStr, SimpleHttpClient.ENCODING_UTF_8);

                String[] kvpSplits = kvpStr.split("=", 2);

                if(kvpSplits.length == 2)
                {
                    kvpList.put(kvpSplits[0], kvpSplits[1]);
                }
                else if(kvpSplits.length == 1)
                {
                    kvpList.put(kvpSplits[0], "");
                }
            }
            catch (UnsupportedEncodingException ex)
            {
                throw ex;
            }
        }
    }

    public static class SimpleHttpClient
    {
        public static final String ENCODING_UTF_8 = "UTF-8";
        public static final int DEFAULT_TIMEOUT = 10000;

        public static final String HTTP_GET = "GET";

        public String execute(String urlStr, String httpMethod, int timeout) throws IOException
        {
            URL url = null;
            HttpURLConnection conn = null;
            InputStream inStream = null;
            OutputStream outStream = null;
            String response = null;

            try
            {
                url = new URL(urlStr);
                conn = (HttpURLConnection) url.openConnection();
                conn.setConnectTimeout(timeout);
                conn.setRequestMethod(httpMethod);

                inStream = new BufferedInputStream(conn.getInputStream());
                response = getInput(inStream);
            }
            finally
            {
                if(conn != null && conn.getErrorStream() != null)
                {
                    String errorResponse = " : ";
                    errorResponse = errorResponse + getInput(conn.getErrorStream());
                    response = response + errorResponse;
                }

                if (conn != null)
                {
                    conn.disconnect();
                }
            }

            return response;
        }

        private String getInput(InputStream in) throws IOException
        {
            StringBuilder sb = new StringBuilder(8192);
            byte[] b = new byte[1024];
            int bytesRead = 0;

            while (true)
            {
                bytesRead = in.read(b);
                if (bytesRead < 0)
                {
                    break;
                }
                String s = new String(b, 0, bytesRead, ENCODING_UTF_8);
                sb.append(s);
            }

            return sb.toString();
        }

    }
}

Here is the test code:

下面是测试代码:

public static void main(String[] args)
{
    String youTubeVideoID = "v1uyQZNg2vE";

    YouTubeVideoInfoRetriever retriever = new YouTubeVideoInfoRetriever();

    try
    {
        retriever.retrieve(youTubeVideoID);
        System.out.println(retriever.getInfo(YouTubeVideoInfoRetriever.KEY_DASH_VIDEO));
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

回答by sajad abbasi

to play youtube video in exoplayer we can use this library

要在 exoplayer 中播放 youtube 视频,我们可以使用这个库

https://github.com/HaarigerHarald/android-youtubeExtractor

and simply get the url like this and then play in exoplyer

并简单地获取这样的网址,然后在 exoplyer 中播放

String youtubeLink = "http://youtube.com/watch?v=xxxx";

new YouTubeExtractor(this) {
    @Override
    public void onExtractionComplete(SparseArray<YtFile> ytFiles, VideoMeta vMeta) {
        if (ytFiles != null) {
            int itag = 22;
        String downloadUrl = ytFiles.get(itag).getUrl();
        }
    }
}.extract(youtubeLink, true, true);