从Android应用程序打开Chromecast youtube视频

时间:2014-05-03 21:44:55

标签: android youtube chromecast

我创建了一个应用程序,其中有一个包含youtube链接的列表视图。现在我想使用chrome cast播放这些视频。我按照官方文档,我可以播放直接mp4链接的其他视频,但它不适用于youtube链接。

当然其他链接直接连接到视频(结尾* .mp4),但如何添加带有youtube链接的媒体?不知何故,我需要使用youtube链接创建一个MediaInfo对象,但我不知道该怎么做,或者甚至可能。

我找到了这个信息

MimeData data = new MimeData(“v = g1LsT1PVjUA”,MimeData.TYPE_TEXT); mSession.startSession(“YouTube”,数据);

Open Chromecast YouTube video from my Android app

但我不知道如何获得会话并使用youtube会话加载它。如果有人能帮助我,我将不胜感激。

感谢您的帮助

4 个答案:

答案 0 :(得分:4)

我写了一个Android应用程序,该应用程序去年在大屏幕电视上播放VLC上的YouTube /本地媒体。它演奏得非常好,但我总是想用更优雅的东西取代VLC笔记本电脑。当Chromecast最终与官方SDK一起发布时,我感到非常兴奋。在尝试启动YouTube接收器应用程序播放YouTube视频时,我也遇到了同样的问题,因此我决定深入了解VLC是如何做到这一点的(开源很棒:))我发现YouTube视频ID只是一个JavaScript页面里面嵌入了很多东西。诀窍是从中提取正确的信息。不幸的是,VLC脚本是用Lua编写的,所以我花了几个星期的时间学习Lua来浏览Lua脚本。你可以谷歌youtube.lua获取脚本的源代码。

我用Java重写了脚本,并且能够修改CastVideos Android以轻松播放YouTube视频。请注意,由于Chromecast只能播放mp4视频容器格式,因此其他格式的视频可能无法播放。

如果有人有兴趣,这是我的测试代码。您可以使用CastHelloVideo-chrome加载自定义媒体来测试网址。

享受,

DANH

    package com.dql.urlexplorer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class UrlExplore {

    private static final String URL_ENCODED_STREAM_MAP     = "\"url_encoded_fmt_stream_map\":";
    private static final String VIDEO_TITLE_KEYWORD               = "<meta name=\"title\"";
    private static final String VIDEO_DESCRIPTION_KEYWORD  = "<meta name=\"description\"";
    private static final String VIDEO_THUMBNAIL_KEYWORD    = "<meta property=\"og:image\"" ;
    private static final String CONTENT_VALUE_KEYWORD        = "content=\"";

    //private static final String TEST_URL = "http://www.youtube.com/watch?v=JtyCM4BTbYo";
    private static final String YT_UTRL_PREFIX = "http://www.youtube.com/watch?v=";

    public static void main(String[] args) throws IOException {

        while (true) {
               String videoId = getVideoIdFromUser();

                String urlSite = YT_UTRL_PREFIX + videoId;
                System.out.println("URL =  " + urlSite);
                System.out.println("===============================================================");
                System.out.println("Getting video site content");
                System.out.println("===============================================================");

                CloseableHttpClient httpclient = HttpClients.createDefault();
                try {
                    HttpGet httpget = new HttpGet(urlSite);

                    System.out.println("Executing request " + httpget.getRequestLine());


                    // Create a custom response handler
                    ResponseHandler<String> responseHandler = new ResponseHandler<String>() {

                        public String handleResponse(
                                final HttpResponse response) throws ClientProtocolException, IOException {
                            int status = response.getStatusLine().getStatusCode();
                            if (status >= 200 && status < 300) {
                                HttpEntity entity = response.getEntity();
                                return entity != null ? EntityUtils.toString(entity) : null;
                            } else {
                                throw new ClientProtocolException("Unexpected response status: " + status);
                            }
                        }

                    };
                    String responseBody = httpclient.execute(httpget, responseHandler);

                    if (responseBody.contains(VIDEO_TITLE_KEYWORD)) {
                        // video title
                        int titleStart = responseBody.indexOf(VIDEO_TITLE_KEYWORD);
                        StringBuilder title = new StringBuilder();
                        char ch;
                        do {
                            ch = responseBody.charAt(titleStart++);
                            title.append(ch);
                        }
                        while (ch != '>');
                        String videoTitle = getKeyContentValue(title.toString());
                         System.out.println("Video Title =  " + videoTitle);
                    }
                    if (responseBody.contains(VIDEO_DESCRIPTION_KEYWORD)) {
                        // video description
                        int descStart = responseBody.indexOf(VIDEO_DESCRIPTION_KEYWORD);
                        StringBuilder desc = new StringBuilder();
                        char ch;
                        do {
                            ch = responseBody.charAt(descStart++);
                            desc.append(ch);
                        }
                        while (ch != '>');
                        String videoDesc = getKeyContentValue(desc.toString());
                         System.out.println("Video Description =  " + videoDesc);                       
                    }
                    if (responseBody.contains(VIDEO_THUMBNAIL_KEYWORD)) {
                        // video thumbnail
                        int thumbnailStart = responseBody.indexOf(VIDEO_THUMBNAIL_KEYWORD);
                        StringBuilder thumbnailURL = new StringBuilder();
                        char ch;
                        do {
                            ch = responseBody.charAt(thumbnailStart++);
                            thumbnailURL.append(ch);
                        }
                        while (ch != '>');
                        String videoThumbnail= getKeyContentValue(thumbnailURL.toString());
                         System.out.println("Video Thumbnail =  " + videoThumbnail);                        
                    }
                    if (responseBody.contains(URL_ENCODED_STREAM_MAP)) {
                        // find the string we are looking for
                        int start = responseBody.indexOf(URL_ENCODED_STREAM_MAP) + URL_ENCODED_STREAM_MAP.length() + 1;  // is the opening "
                        String urlMap = responseBody.substring(start);
                        int end = urlMap.indexOf("\"");
                        if (end > 0) {
                            urlMap = urlMap.substring(0, end);
                        }
                        String path = getURLEncodedStream(urlMap);
                        System.out.println("Video URL = " + path);
                    }

                }
                finally {
                    httpclient.close();
                }
                System.out.println( "===============================================================");
                System.out.println("Done: ");
                System.out.println("===============================================================");      
        }

    }

    static String getURLEncodedStream(String stream) throws UnsupportedEncodingException {
        // replace all the \u0026 with &
         String str = stream.replace("\\u0026", "&");
        //str = java.net.URLDecoder.decode(stream, "UTF-8");
        //System.out.println("Raw URL map = " + str);
        String urlMap = str.substring(str.indexOf("url=http") + 4);
        // search urlMap until we see either a & or ,
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < urlMap.length(); i++) {
            if ((urlMap.charAt(i) == '&') || (urlMap.charAt(i) == ','))
                break;
            else
                sb.append(urlMap.charAt(i));
        }
        //System.out.println(java.net.URLDecoder.decode(sb.toString(),"UTF-8"));
        return java.net.URLDecoder.decode(sb.toString(),"UTF-8");

    }

    static String getKeyContentValue(String str) {
        StringBuilder contentStr = new StringBuilder();
        int contentStart = str.indexOf(CONTENT_VALUE_KEYWORD) + CONTENT_VALUE_KEYWORD.length();
        if (contentStart > 0) {
            char ch;
            while (true) {
                ch = str.charAt(contentStart++);
                if (ch == '\"')
                    break;
                contentStr.append(ch);
            }
        }
        try {
            return java.net.URLDecoder.decode(contentStr.toString(),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /*
     * Prompt the user to enter a video ID.
     */
    private static String getVideoIdFromUser() throws IOException {

        String videoId = "";

        System.out.print("Please enter a YouTube video Id: ");
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        videoId = bReader.readLine();

        if (videoId.length() < 1) {
            // Exit if the user doesn't provide a value.
            System.out.print("Video Id can't be empty! Exiting program");
            System.exit(1);
        }

        return videoId;
    }

}`enter code here`

答案 1 :(得分:1)

我最近写了一个库来解决这个问题。 chromecast-sender。它是android-youtube-player库的扩展库,可轻松将视频从Android应用投射到Google Cast设备。

接收者使用YouTube IFrame播放器API。发件人和接收者通过自定义渠道进行通信。

答案 2 :(得分:0)

你不能用官方SDK做到这一点。有些人使用过iframe方法,但有不同的成功报告。

答案 3 :(得分:0)

我们可以使用当前的chromecast设备加入实时会话:使用下面的回调告诉我如果您想要同样如下,那么我将发送剩余部分代码。

private final GoogleApiClient.ConnectionCallbacks connectionCallback = new GoogleApiClient.ConnectionCallbacks() {
        @Override
        public void onConnected(Bundle bundle) {
            // SDK confirms that GoogleApiClient is connected: GoogleApiClient.ConnectionCallbacks.onConnected
            Trace.d(TAG, "GoogleApiClient.ConnectionCallbacks # onConnected()");

            try {
                // Sender app launches or join the receiver app: Cast.CastApi.launchApplication
                Cast.CastApi.joinApplication(mApiClient).setResultCallback(connectionResultCallback);
            } catch (Exception e) {
                Trace.d(TAG, "Failed to join application");
            }
        }

        @Override
        public void onConnectionSuspended(int i) {
            Trace.d(TAG, "GoogleApiClient.ConnectionCallbacks # onConnectionSuspended()");
            try {
                Cast.CastApi.leaveApplication(mApiClient);
            } catch (Exception e) {
                Trace.d(TAG, "Failed to join application");
            }
        }
    };