Close
Advertise Here
Results 1 to 5 of 5
  1. #1


    Embedding Youtube videos into your OUYA app

    OUYA doesn't have the Youtube app, so unfortunately you can't use the normal Youtube API for android.

    However, after mashing together a couple of different solutions I found on the web, I managed to get full HD video streaming from a video on my youtube channel to a "VideoView" inside my game:

    Code:
    	private VideoView myvideoview;
    	
    	static final String YOUTUBE_VIDEO_INFORMATION_URL = "http://www.youtube.com/get_video_info?&video_id=";
    	
    	private void initVideo() {
    		
    		setContentView(R.layout.video_guide_main);
    		
    		myvideoview = (VideoView) findViewById(R.id.video_guide_main_videoView1);
    		
    		new VideoAsyncTask().execute();
    			
    		
    	}
    	
    	//////////////////////////// http://stackoverflow.com/questions/17448709/stream-youtube-videos-without-youtube-app
    
    	private class VideoAsyncTask extends AsyncTask<Void, Void, Void> {
    	    ProgressDialog progressDialog;
    	    String videoUrl;
    
    	    @Override
    	    protected void onPreExecute() {
    	        super.onPreExecute();
    	        progressDialog = ProgressDialog.show(VideoGuideActivity.this, "",
    	                "Loading Video wait...", true);
    	    }
    
    	    @Override
    	    protected Void doInBackground(Void... params) {
    	        try {
    
    	            String id = "eHz0b17pa1g"; //id of video (i.e. http://www.youtube.com/watch?v=eHz0b17pa1g ) 
    
    	            videoUrl = calculateYouTubeUrl("37", true, id);
    	            Log.e("Video url for playing=========>>>>>", videoUrl);
    	        } catch (Exception e) {
    	            Log.e("Login Soap Calling in Exception", e.toString());
    	        }
    	        return null;
    	    }
    
    	    @Override
    	    protected void onPostExecute(Void result) {
    	        super.onPostExecute(result);
    	        progressDialog.dismiss();
    
    	        if (myvideoview.isPlaying())
    	            myvideoview.stopPlayback();
    	        myvideoview.setVideoURI(Uri.parse(videoUrl));
    	        MediaController mc = new MediaController(VideoGuideActivity.this);
    	        myvideoview.setMediaController(mc);
    	        myvideoview.requestFocus();
    
    	        myvideoview.start();
    	        mc.show();
    	    }
    
    	}
    	
    	///////////////////////////// http://code.google.com/p/android-youtube-player/
    	
        /**
         * Calculate the YouTube URL to load the video.  Includes retrieving a token that YouTube
         * requires to play the video.
         *
         * @param pYouTubeFmtQuality quality of the video.  17=low, 18=high
         * @param bFallback whether to fallback to lower quality in case the supplied quality is not available
         * @param pYouTubeVideoId the id of the video
         * @return the url string that will retrieve the video
         * @throws IOException
         * @throws ClientProtocolException
         * @throws UnsupportedEncodingException
         */
    	public static String calculateYouTubeUrl(String pYouTubeFmtQuality, boolean pFallback,
                        String pYouTubeVideoId) throws IOException,
                        ClientProtocolException, UnsupportedEncodingException {
    
                String lUriStr = null;
                HttpClient lClient = new DefaultHttpClient();
               
                HttpGet lGetMethod = new HttpGet(VideoGuideActivity.YOUTUBE_VIDEO_INFORMATION_URL +
                                                                                 pYouTubeVideoId);
               
                HttpResponse lResp = null;
    
                lResp = lClient.execute(lGetMethod);
                       
                ByteArrayOutputStream lBOS = new ByteArrayOutputStream();
                String lInfoStr = null;
                       
                lResp.getEntity().writeTo(lBOS);
                lInfoStr = new String(lBOS.toString("UTF-8"));
               
                String[] lArgs=lInfoStr.split("&");
                Map<String,String> lArgMap = new HashMap<String, String>();
                for(int i=0; i<lArgs.length; i++){
                        String[] lArgValStrArr = lArgs[i].split("=");
                        if(lArgValStrArr != null){
                                if(lArgValStrArr.length >= 2){
                                        lArgMap.put(lArgValStrArr[0], URLDecoder.decode(lArgValStrArr[1]));
                                }
                        }
                }
               
                //Find out the URI string from the parameters
               
                //Populate the list of formats for the video
                String lFmtList = URLDecoder.decode(lArgMap.get("fmt_list"));  // <----- this string lists all the available video formats and their corresponding number codes   
                ArrayList<VideoFormat> lFormats = new ArrayList<VideoFormat>();
                if(null != lFmtList){
                        String lFormatStrs[] = lFmtList.split(",");
                       
                        for(String lFormatStr : lFormatStrs){
                                VideoFormat lFormat = new VideoFormat(lFormatStr);
                                lFormats.add(lFormat);
                        }
                }
               
                //Populate the list of streams for the video
                String lStreamList = lArgMap.get("url_encoded_fmt_stream_map");
                if(null != lStreamList){
                        String lStreamStrs[] = lStreamList.split(",");
                        ArrayList<VideoStream> lStreams = new ArrayList<VideoStream>();
                        for(String lStreamStr : lStreamStrs){
                                VideoStream lStream = new VideoStream(lStreamStr);
                                lStreams.add(lStream);
                        }      
                       
                        //Search for the given format in the list of video formats
                        // if it is there, select the corresponding stream
                        // otherwise if fallback is requested, check for next lower format
                        int lFormatId = Integer.parseInt(pYouTubeFmtQuality);
                       
                        VideoFormat lSearchFormat = new VideoFormat(lFormatId);
                        while(!lFormats.contains(lSearchFormat) && pFallback ){
                                int lOldId = lSearchFormat.getId();
                                int lNewId = getSupportedFallbackId(lOldId);
                               
                                if(lOldId == lNewId){
                                        break;
                                }
                                lSearchFormat = new VideoFormat(lNewId);
                        }
                       
                        int lIndex = lFormats.indexOf(lSearchFormat);
                        if(lIndex >= 0){
                                VideoStream lSearchStream = lStreams.get(lIndex);
                                lUriStr = lSearchStream.getUrl();
                        }
                       
                }              
                //Return the URI string. It may be null if the format (or a fallback format if enabled)
                // is not found in the list of formats for the video
                return lUriStr;
        }
    	
        public static int getSupportedFallbackId(int pOldId){
            final int lSupportedFormatIds[] = {13,  //3GPP (MPEG-4 encoded) Low quality
                                                                              17,  //3GPP (MPEG-4 encoded) Medium quality
                                                                              18,  //MP4  (H.264 encoded) Normal quality
                                                                              22,  //MP4  (H.264 encoded) High quality
                                                                              37   //MP4  (H.264 encoded) High quality
                                                                              };
            int lFallbackId = pOldId;
            for(int i = lSupportedFormatIds.length - 1; i >= 0; i--){
                    if(pOldId == lSupportedFormatIds[i] && i > 0){
                            lFallbackId = lSupportedFormatIds[i-1];
                    }                      
            }
            return lFallbackId;
        }

    You'll also need these two helper classes:

    Code:
    package com.yourpackage;
    
    /**
     * Represents a format in the "fmt_list" parameter
     * Currently, only id is used
     *
     */
    public class VideoFormat {
    
            protected int mId;
           
            /**
             * Construct this object from one of the strings in the "fmt_list" parameter
             * @param pFormatString one of the comma separated strings in the "fmt_list" parameter
             */
            public VideoFormat(String pFormatString){
                    String lFormatVars[] = pFormatString.split("/");
                    mId = Integer.parseInt(lFormatVars[0]);
            }
            /**
             * Construct this object using a format id
             * @param pId id of this format
             */
            public VideoFormat(int pId){
                    this.mId = pId;
            }
           
            /**
             * Retrieve the id of this format
             * @return the id
             */
            public int getId(){
                    return mId;
            }
            /* (non-Javadoc)
             * @see java.lang.Object#equals(java.lang.Object)
             */
            @Override
            public boolean equals(Object pObject) {
                    if(!(pObject instanceof VideoFormat)){
                            return false;
                    }
                    return ((VideoFormat)pObject).mId == mId;
            }
    }
    Code:
    package com.yourpackage;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * Represents a video stream
     *
     */
    public class VideoStream {
           
            protected String mUrl;
           
            /**
             * Construct a video stream from one of the strings obtained
             *      from the "url_encoded_fmt_stream_map" parameter if the video_info
             * @param pStreamStr - one of the strings from "url_encoded_fmt_stream_map"
             */
            public VideoStream(String pStreamStr){
                    String[] lArgs=pStreamStr.split("&");
                    Map<String,String> lArgMap = new HashMap<String, String>();
                    for(int i=0; i<lArgs.length; i++){
                            String[] lArgValStrArr = lArgs[i].split("=");
                            if(lArgValStrArr != null){
                                    if(lArgValStrArr.length >= 2){
                                            lArgMap.put(lArgValStrArr[0], lArgValStrArr[1]);
                                    }
                            }
                    }
                    mUrl = lArgMap.get("url") + "&signature=" + lArgMap.get("sig");
            }
            public String getUrl(){
                    return mUrl;
            }
    }
    @JamesACoote
    Executive Star now available on OUYA Discover

  2. #2
    OUYA Devotee DoubleD's Avatar
    Join Date
    Oct 2012
    Location
    ŔĩɢɦŦ ɓ£ɦĩהƊ ¥øŪ (Belgium)
    Posts
    184


    Does this take over the whole screen or is it possible to add screens in a 3d environment like banners on the side of a racetrack playing YouTube videos?

    Not that I would be able to use this, I am just curious.
    This day is grim, it is raining. What wonderful weather for Gaming!
    Sun's blazing, so let's stay in. It's wonderful weather for Gaming!

  3. #3
    OUYA Developer Lucas Junqueira's Avatar
    Join Date
    Jul 2013
    Location
    Brazil / Belo Horizonte
    Posts
    19


    1 members found this post helpful.
    If you're using Adobe AIR for development you can use the StageWebView class (http://help.adobe.com/en_US/FlashPla...geWebView.html) to do the trick. It can show the Youtube interface as a layer above your content. You'll need to add some html files to host the Youtube embed iframe (the best way I found) and deal with the unpacking and temporary save of these html files, but it is quite possible and not as hard as it seems...
    Last edited by Lucas Junqueira; 08-13-2013 at 05:57 PM. Reason: typo

  4. #4


    Quote Originally Posted by DoubleD View Post
    Does this take over the whole screen or is it possible to add screens in a 3d environment like banners on the side of a racetrack playing YouTube videos?

    Not that I would be able to use this, I am just curious.
    It's an android view widget, so not in any easy/practical way.
    @JamesACoote
    Executive Star now available on OUYA Discover

  5. #5


    If you would go through the fuss of stripping the frame data from mp4 and putting into a buffer that is rasterized into a texture in game, you would have some killer performance issues. I'd personally would rather spend the CPU time on a more complex AI algorithm or add more polygons or post post processing effects...

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •