zoukankan      html  css  js  c++  java
  • Android使用VideoView播放本地视频和youtube视频

    其中播放youtube视频的核心代码借鉴网上开源代码。
    代码如下:
    Format.java

    /**
     * Represents a format in the "fmt_list" parameter
     * Currently, only id is used
     *
     */
    public class Format {
    
        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 Format(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 Format(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 Format)){
                return false;
            }
            return ((Format)pObject).mId == mId;
        }
    }


    VideoStream.java

    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");
        }
        public String getUrl(){
            return mUrl;
        }
    }


    YouTubeUtility.java

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map;
     
    import org.apache.http.HttpResponse;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
     
    public class YouTubeUtility {
        
        private static final String YOUTUBE_VIDEO_INFORMATION_URL = "http://www.youtube.com/get_video_info?&video_id=";
        /**
         * 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(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"));
            ArrayList<Format> lFormats = new ArrayList<Format>();
            if(null != lFmtList){
                String lFormatStrs[] = lFmtList.split(",");
                
                for(String lFormatStr : lFormatStrs){
                    Format lFormat = new Format(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);
                
                Format lSearchFormat = new Format(lFormatId);
                while(!lFormats.contains(lSearchFormat) && pFallback ){
                    int lOldId = lSearchFormat.getId();
                    int lNewId = getSupportedFallbackId(lOldId);
                    
                    if(lOldId == lNewId){
                        break;
                    }
                    lSearchFormat = new Format(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;
        }
    } 


    播放代码:

        /** 弹出视频的Layout容器 */
        private RelativeLayout popUpVideoLayout;
        /** 弹出视频播放器 */
        private VideoView popUpVideoView;
        /** 视频是否执行的监控线程的执行标志位 */
        private int vedioThreadProcess;
        /** 是否改变isAutoOrientation的标志位
         * 如果改变了,在视频关闭时要改回来;如果没有改变则不需要改变回来 */
        private boolean hasChangedAutoOrientation = false;
        /** 视频文件已经加载完毕 */
        private boolean hasVideoPrepared = false;
        
        public class VideoCtlHandler extends Handler {
            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                //super.handleMessage(msg);
                switch (msg.what) {
                case 83 :
                    // 当视频正在播放状态时,不显示播放和关闭按钮
                    Log.e("msg.what", String.valueOf(msg.what));
                    if (CTplayBtn.getVisibility() == View.VISIBLE
                            && CTcloseBtn.getVisibility() == View.VISIBLE) {
                        CTplayBtn.setVisibility(View.GONE);
                        CTcloseBtn.setVisibility(View.GONE);
                        Log.e("CTplayBtn&CTcloseBtn", "GONE");                    
                    }
                    break;
                case 38 :
                    // 当视频在没有播放的状态时,显示播放和关闭按钮
                    if (CTplayBtn.getVisibility() == View.GONE
                            && CTcloseBtn.getVisibility() == View.GONE) {
                    CTplayBtn.setVisibility(View.VISIBLE);
                    CTcloseBtn.setVisibility(View.VISIBLE);
                    Log.e("CTplayBtn&CTcloseBtn", "VISIBLE");
                    }
                    break;
                }
            }
          }
        
        /**
         * 关闭当前播放弹出视窗中播放的视频(单击播放的视频).
         * */
        private void closePopUpVideo() {
            if (popUpVideoView != null) {
                if (hasChangedAutoOrientation ==  true) {
                    switchAutoOrientation(this, true);                
                }
                vedioThreadProcess = 0;
                popUpVideoView.stopPlayback();
                popUpVideoView.setMediaController(null);
                popUpVideoView = null;
                popUpVideoLayout.removeAllViews();
                mLytMain.removeView(popUpVideoLayout);
            }
        }
        
        public static void switchAutoOrientation(XXXXXXXNew ap, boolean toggleSetting) {
            if (toggleSetting)
                isAutoOrientation = !isAutoOrientation;
    
            if (getAutoOrientation() == true) {
                ap.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
            } else {
                // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
                if (ap.getDisplaySize().isLandscape())
                    ap
                            .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                else
                    ap
                            .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
        }
        /**
         * 弹出窗体显示本机视频
         * */
        private void popUpLocalVideo(String data, String sMediaPath, String youtubeUrl, AbsoluteLayout.LayoutParams params,
                boolean isYoutube) {
            if (!isYoutube) {
                if (!DRMControl.unzipFile(data, sMediaPath)) {
                    Log.i("Err", "------------------unzipFile media failed !");
                    return;
                }            
            }
            hasVideoPrepared = false;
            // 如果已经有视频在播放,则关闭
            closePopUpVideo();
            // 在视频播放时控制pad屏幕不可旋转
            if (isAutoOrientation == true) {
                switchAutoOrientation(this, true);
                hasChangedAutoOrientation = true;
            } else {
                switchAutoOrientation(this, false);
                hasChangedAutoOrientation = false;
            }
    
            vHandler = new VideoCtlHandler();
            // 添加视频播放器
            popUpVideoLayout = new RelativeLayout(context);
            popUpVideoView = new VideoView(context);
            RelativeLayout.LayoutParams textParams2 = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.FILL_PARENT,
                    RelativeLayout.LayoutParams.FILL_PARENT);
            textParams2.addRule(RelativeLayout.CENTER_IN_PARENT);
            popUpVideoLayout.addView(popUpVideoView, textParams2);
            
            // 添加播放按钮
            CTplayBtn = new ImageButton(context);
            CTplayBtn.setBackgroundResource(R.drawable.play);
            RelativeLayout.LayoutParams playBtnParams = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            playBtnParams.addRule(RelativeLayout.CENTER_VERTICAL);
            if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                playBtnParams.leftMargin = mScreenRect.width()/2 - 100;
            } else {
                playBtnParams.leftMargin = mScreenRect.width()/8 + 50;
            }
            popUpVideoLayout.addView(CTplayBtn, playBtnParams);
            CTplayBtn.setVisibility(View.GONE);
            CTplayBtn.setOnClickListener(new OnClickListener(){
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    popUpVideoView.setMediaController(new MediaController(context));
                    popUpVideoView.start();
                    CTplayBtn.setVisibility(View.GONE);
                    CTcloseBtn.setVisibility(View.GONE);
                }
                
            });
            
            // 添加关闭按钮
            CTcloseBtn = new ImageButton(context);
            CTcloseBtn.setBackgroundResource(R.drawable.pause);
            RelativeLayout.LayoutParams closeBtnParams = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            closeBtnParams.addRule(RelativeLayout.CENTER_VERTICAL);
            if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                closeBtnParams.leftMargin = mScreenRect.width()/2 + 100;
            } else {
                closeBtnParams.leftMargin = mScreenRect.width()*3/8 - 50;;
            }
            popUpVideoLayout.addView(CTcloseBtn, closeBtnParams);
            CTcloseBtn.setVisibility(View.GONE);
            CTcloseBtn.setOnClickListener(new OnClickListener(){
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    closePopUpVideo();
                }
                
            });
            if (!isYoutube) {
                // 播放本地视频
                String sPath = sMediaPath + data;
                popUpVideoView.setVideoPath(sPath);
            } else {
                // 播放youtube视频
                String lUriStr = "";
                try{
                     lUriStr = YouTubeUtility.calculateYouTubeUrl("18", true, getVideoId(youtubeUrl));
                } catch (Exception e) {
                    
                }
                if ("".equals(lUriStr)) {
                    return;
                }
                popUpVideoView.setVideoURI(Uri.parse(lUriStr));
            }
            MediaController mediaController = new MediaController(this);
            mediaController.setAnchorView(popUpVideoView);
            popUpVideoView.setMediaController(mediaController);
            //videoView.requestFocus();
            popUpVideoView.setOnPreparedListener(new OnPreparedListener() {
                public void onPrepared(MediaPlayer mp) {
                    mp.start();
                    hasVideoPrepared = true;
                }
            });
            
            // 视频播放状态监控线程
            vedioThreadProcess = 1;
            vThread = new Thread() {
                @Override
                public void run() {
                    while (vedioThreadProcess == 1) {
                        try{
                            sleep(700);                        
                        } catch (Exception e) {
                            
                        }
                        // 当视频正在播放状态时
                        if (popUpVideoView != null && popUpVideoView.getParent() != null
                                && hasVideoPrepared && popUpVideoView.isPlaying()) {
                            Log.e("videoView", "is playing");
                            vHandler.sendEmptyMessage(83);
                        }
                        // 当视频在非播放状态时
                        if (popUpVideoView != null && popUpVideoView.getParent() != null
                                && hasVideoPrepared && !popUpVideoView.isPlaying()) {
                            Log.e("videoView", "is not playing");
                            vHandler.sendEmptyMessage(38);
                        }
                    }
                }
            };
            vThread.start();
            
            // 视频播放器点击事件,停止视频播放并且显示播放和关闭按钮
            popUpVideoView.setOnTouchListener(new OnTouchListener() {
    
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN :{
                        popUpVideoView.pause();
                        // popUpVideoView.setMediaController(null);
                        CTplayBtn.setVisibility(View.VISIBLE);
                        CTcloseBtn.setVisibility(View.VISIBLE);
                        break;
                    }
                    case MotionEvent.ACTION_UP : break;
                    case MotionEvent.ACTION_MOVE : return false;
                    }
                    
                    return false;
                }
                
            });
            mLytMain.addView(popUpVideoLayout, params);
        }
  • 相关阅读:
    PHP新的垃圾回收机制:Zend GC详解
    SSH隧道技术简介
    mysql主从延迟
    非root配置linux下vim
    PHP 中的 9 个魔术方法
    PHP内核介绍及扩展开发指南—Extensions 的编写(下)
    PHP内核介绍及扩展开发指南—Extensions 的编写
    php 扩展开发
    php opcode
    rsa 数学推论
  • 原文地址:https://www.cnblogs.com/sipher/p/2624954.html
Copyright © 2011-2022 走看看