문제

I created an app in which there is a list view with youtube links. Now I want to play these videos using chrome cast. I followed the official documentation and I am able to play other videos with direct mp4 link, but its not working for youtube links.

Of course the other links are directly connected to a video (ending *.mp4), but how can i add a media with a youtube link? Somehow I need to create a MediaInfo object with youtube link, but I don't know how to do that or is it even possible.

I have found this information

MimeData data = new MimeData("v=g1LsT1PVjUA", MimeData.TYPE_TEXT); mSession.startSession("YouTube", data);

Open Chromecast YouTube video from my Android app

But I am not sure how to get the session and load it with youtube session. I would appreciate if someone can help me with this.

Thanks for your help

도움이 되었습니까?

해결책

I wrote an Android app that plays YouTube/Local media on VLC attached to a big screen TV last year. It was playing very nice but I always want to replace the VLC laptop with something more elegant. I was really excited when Chromecast was finally released with an official SDK. I too ran into the same problem when trying to launch YouTube receiver app to play YouTube video so I decided to delve into how VLC was able to do that (Is open source great :)) I found out that the YouTube video ID is just a JavaScript page with lots of stuff embedded inside. The trick is to pull out the correct info from it. Unfortunately, the VLC script is written in Lua so I spent a couple weeks learning enough Lua to navigate my way around the Lua script. You can google youtube.lua for the source code of the script.

I rewrote the script in Java and was able to modify CastVideos Android to play YouTube video at ease. Note that since Chromecast can only play mp4 video container format, video in other format may not play.

Here is my test code if anyone is interested. You can test the URL using CastHelloVideo-chrome load custom media.

Enjoy,

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`

다른 팁

I recently wrote a library to solve this problem. chromecast-sender. It is an extension library for the android-youtube-player library and makes it easy to cast videos from an Android app to a Google Cast device.

The receiver uses the YouTube IFrame player API. Sender and Receiver communicate through a custom channel.

You cannot do that with the official SDK. Some folks have used iframe approach but there is varying reports of success.

We can join with live session usign current chromecast device: Use the below call back and let me know if you want the same as below then i will send remaining part of the code.

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");
            }
        }
    };
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top