Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play High-Quality Youtube Videos Using VideoView

I'm working on a music APP that displays lyrics and info about songs and also plays songs from a youtube URL.

In my activity, there are some TextViews (for the lyrics/info) and one VideoView (for the youtube link).

I've created a class called YoutubeVideo, that does the following:

  1. Downloads the content of this page: http://gdata.youtube.com/feeds/api/videos?q=SONG_NAME&v=2&max-results=1, parses it's content and gets the youtube's id (e.g EvuL5jyCHOw). This is a RSS feeds page that searches for videos and display 1 result (And all I need to do is to change the query).
  2. Downloads the content of this page: http://gdata.youtube.com/feeds/api/videos?q=YOUTUBES_ID&format=1&alt=json, parses it's content and gets the rtsp (e.g rtsp://v7.cache3...3gp). This is an XML file that holds some information about the video (name, length, thumbnail and of course - rtsp link :).
  3. Than all I need to do is to set the rtsp as VideoURI: VideoView.setVideoURI(Uri.parse(rtsp)) and the video is being played.

If you wonder, I use this class like that: new YoutubeVideo(VideoView).setVideo(artist + " " + title);

It works, but I got one problem: It's a 3gp file... Which has really bad quality. How can I get better quality urls? (mp4/flv/ect?)

like image 572
eviabs Avatar asked Nov 24 '12 00:11

eviabs


2 Answers

I managed to write a function that gets a youtube video html code (the html source code) and returns an array with all of the available video links. Then I select a hight quality link, and display it instead of the poor 3gp.

It's not perfect, and there may be some bugs and improvments to make:

    protected String[] extractLinks(String result) {
    //The title of the downloaded file
    String title = "bla bla bla";
    // An array of strings that will hold the links (in case of error, it will hold 1 string)
    String[] temper = new String[1];

    try{
        // Extract the "url_encoded_fmt_stream_map" attr from the flash object
        Pattern p = Pattern.compile("url_encoded_fmt_stream_map(.*?);");          
        Matcher m = p.matcher(result);
        List<String> matches = new ArrayList<String>();
        while(m.find()){
            matches.add(m.group().replace("url_encoded_fmt_stream_map=", "").replace(";", ""));                   
        }
        String[] streamMap = null;
        List<String> links = new ArrayList<String>();

        if(matches.get(0) != null &&  matches.get(0) != ""){
            // Split the "url_encoded_fmt_stream_map" into an array of strings that hold the link values
            streamMap = matches.get(0).split("%2C");
            for (int i = 0; i < streamMap.length; i++){
                String url = "";
                String sig = "";

                //Using regex, we will get the video url.
                Pattern p2 = Pattern.compile("url%3D(.*?)%26");       
                Matcher m2 = p2.matcher(streamMap[i]);
                List<String> matches2 = new ArrayList<String>();
                while(m2.find()){
                    // We don't need the "url=...&" part.
                    matches2.add(m2.group().substring(6, m2.group().length() - 3));
                }                     
                url = matches2.get(0);   

                //Using regex again, we will get the video signature.               
                p2 = Pattern.compile("sig%3D(.*?)%26");       
                m2 = p2.matcher(streamMap[i]);
                matches2 = new ArrayList<String>();
                while(m2.find()){
                // We don't need the "sig=...&" part.               
                    matches2.add(m2.group().substring(6, m2.group().length() - 3));
                }                     
                sig = matches2.get(0);   

                //Now lets add a link to our list. Link = url + sig + title.
                links.add(URLDecoder.decode(URLDecoder.decode(url + "&signature=", "UTF-8") + sig + "%26title%3D" + URLDecoder.decode(title, "UTF-8"), "UTF-8"));
            }
        }
        else{
        links.add("No download Links");
        }
        //Now lets make temper point to a array that holds the list items (aka links).
        temper = links.toArray(new String[links.size()]);
    }
    catch(Exception ex){
    temper[0] = ex.getMessage();
    }
    // That's it! temper has direct download links from youtube!
    return temper;
}
like image 50
eviabs Avatar answered Sep 22 '22 12:09

eviabs


I strongly recommend you to use Official YouTube Api.

Please download the example zip file at link and see FullscreenDemoActivity.java file. That implemented most of you wanted. just click and show embedded YouTube video in high quality, full screen toggle, and automatically-show-fullscreen-when-rotation.

like image 32
Youngjae Avatar answered Sep 22 '22 12:09

Youngjae