<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>


       To build a better world !

    Android平臺(tái)下SeeJoPlayer視頻播放器(功能介紹及源碼解析,附源碼)


        轉(zhuǎn)載請(qǐng)注明出處:http://m.tkk7.com/zh-weir/archive/2010/01/24/310617.html


        2010.03.27    SeeJoPlayer v1.2.0 beta版:  

         下載SeeJoPlayer v1.2.0 beta     下載SeeJoPlayer v1.2.0 beta源碼


        更新說(shuō)明:

        1、完美支持android1.5、android1.6、android2.0、android2.01、android2.1平臺(tái);
        2、完美支持320×480、480×800、480×854等各種分辨率(自適應(yīng)屏幕分辨率);
        3、支持在線(xiàn)音視頻播放,支持URL input和從瀏覽器調(diào)用SeeJoPlayer播放器播放在線(xiàn)音視頻;
        4、自動(dòng)轉(zhuǎn)為橫屏播放,為用戶(hù)提供更好的觀(guān)看體驗(yàn);
        5、修改了沒(méi)有SD卡程序出錯(cuò)的Bug;
        6、美化了視頻播放列表和操作說(shuō)明的界面。

        補(bǔ)充圖片:
        




    URL輸入功能

        




    瀏覽器中調(diào)用SeeJoPlayer播放


        感謝大家對(duì)SeeJoPlayer的大力支持!希望新版本能帶給大家更好的體驗(yàn)!


        2010.01.24    SeeJoPlayer v1.0.0版: 

        SeeJoPlayer是我利用業(yè)余時(shí)間開(kāi)發(fā)的一款免費(fèi)的視頻播放器。主要是現(xiàn)在在網(wǎng)上似乎找不到一個(gè)Android平臺(tái)下的界面美觀(guān)一點(diǎn)的視頻播放器。而作為智能手機(jī)操作系統(tǒng)的Android,沒(méi)有一個(gè)像樣一點(diǎn)的視頻播放器,豈不糗大了。所以,我就寫(xiě)了這么一個(gè)磚頭并開(kāi)出源碼,希望能引出高手們的美玉來(lái)吧!


             下載APK程序         下載源代碼         轉(zhuǎn)到eoeMarket發(fā)布頁(yè)

        



     第一部分:功能介紹


        SeeJoPlayer的優(yōu)點(diǎn)主要在相對(duì)還算美觀(guān)的界面和便捷的交互操作上。先說(shuō)操作吧,它支持:

        1、全屏切換:       雙擊屏幕
        2、播放/暫停:     長(zhǎng)按屏幕
        3、靜音/恢復(fù):     長(zhǎng)按音量按鈕
        4、播放列表:       控制面板最右邊的按鈕(暫不支持編輯功能)
        5、音量調(diào)節(jié):       單擊音量按鈕,在彈出的音量顯示區(qū)域觸摸改變音量
     

        這些操作和PC上的播放器較為類(lèi)似,希望大家能用得習(xí)慣。

        至于界面的話(huà),多說(shuō)無(wú)益,直接上圖吧:



    橫屏



    豎屏



    全屏



    非全屏



    播放列表



    介紹說(shuō)明

        好了。功能介紹部分到此為止了。如果您覺(jué)得這個(gè)軟件還行的話(huà),歡迎下載使用!


             下載APK程序         下載源代碼         轉(zhuǎn)到eoeMarket發(fā)布頁(yè)



    第二部分:源碼解析
     

        SeeJoPlayer不是一個(gè)完美的作品,可以說(shuō),它在很多地方都不盡如人意。當(dāng)然一個(gè)完美的作品,也不是我寫(xiě)這款播放器的目的。我只是希望以此為引,結(jié)合大家共同的智慧開(kāi)發(fā)出一款真正完美強(qiáng)大的Android平臺(tái)下的國(guó)產(chǎn)視頻播放器出來(lái)。

        SeeJoPlayer有許多不足之處,例如,它只支持系統(tǒng)默認(rèn)的視頻格式,因?yàn)樗褂孟到y(tǒng)默認(rèn)的解碼器。這,一方面是因?yàn)槿绻ㄟ^(guò)軟解碼的話(huà),播放視頻的效率會(huì)很受影響,另外最主要的原因當(dāng)然還是個(gè)人水平、精力有限,沒(méi)辦法接著往下做了。如果大家覺(jué)得這份代碼還多少有些參考價(jià)值的話(huà),不妨拿去用。只是希望當(dāng)你們以此為參考,開(kāi)發(fā)出真正強(qiáng)大的播放器出來(lái)的時(shí)候,別忘了如果能開(kāi)放源碼的話(huà),一定開(kāi)放出來(lái)。畢竟開(kāi)源軟件就好比能夠進(jìn)化的物種,提供你的DNA出來(lái),讓我們共同的軟件變得越來(lái)越完美吧!

        好了,廢話(huà)不說(shuō)了。播放器的全部源碼本文中已經(jīng)提供了下載地址。下面,我就其中我覺(jué)得可能值得關(guān)注的地方做一些解釋。

        一、VideoView與視頻比例縮放:

        以前在論壇上也看到有人問(wèn)過(guò)如何實(shí)現(xiàn)視頻按比例縮放的問(wèn)題。的確,如果僅僅使用VideoView可能達(dá)不到我們想要達(dá)到的效果。這就需要我們對(duì)VideoView做一些改動(dòng),簡(jiǎn)單的說(shuō)就是另外寫(xiě)一個(gè)類(lèi)似VideoView的類(lèi)出來(lái)(慶幸Android是開(kāi)源的)。

        我們可以很方便的獲得VideoView的源代碼,最簡(jiǎn)單的方法是直接在GoogleCodeSearch上找“VideoView.java”。所以重寫(xiě)VideoView的過(guò)程其實(shí)只是在原來(lái)的基礎(chǔ)上進(jìn)行一些修改而已,并非一個(gè)很麻煩的工作。為什么Android自帶的VideoView會(huì)保持視頻的長(zhǎng)寬比而不能讓我們很方便的自定義比例呢?我猜想可能Google做Android也是一個(gè)很倉(cāng)促的工程,許多代碼并沒(méi)有考慮得太成熟。

        VideoView的源碼中有這樣一段代碼:

     1@Override
     2    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     3        //Log.i("@@@@", "onMeasure");
     4        int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
     5        int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
     6        if (mVideoWidth > 0 && mVideoHeight > 0{
     7            if ( mVideoWidth * height  > width * mVideoHeight ) {
     8                //Log.i("@@@", "image too tall, correcting");
     9                height = width * mVideoHeight / mVideoWidth;
    10            }
     else if ( mVideoWidth * height  < width * mVideoHeight ) {
    11                //Log.i("@@@", "image too wide, correcting");
    12                width = height * mVideoWidth / mVideoHeight;
    13            }
     else {
    14                //Log.i("@@@", "aspect ratio is correct: " +
    15                        //width+"/"+height+"="+
    16                        //mVideoWidth+"/"+mVideoHeight);
    17            }

    18        }

    19        //Log.i("@@@@@@@@@@", "setting size: " + width + 'x' + height);
    20        setMeasuredDimension(width, height);
    21    }

    22

        這就是為什么長(zhǎng)寬比不能改變的原因了。因?yàn)樵贠nMeasure的時(shí)候,就對(duì)這個(gè)長(zhǎng)寬比進(jìn)行了處理。

        我們把其中處理的代碼屏蔽掉,視頻大小就可以隨著VideoView的長(zhǎng)寬改變而改變了。

     1@Override
     2    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     3        //Log.i("@@@@", "onMeasure");
     4        int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
     5        int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
     6        /*if (mVideoWidth > 0 && mVideoHeight > 0) {
     7            if ( mVideoWidth * height  > width * mVideoHeight ) {
     8                //Log.i("@@@", "image too tall, correcting");
     9                height = width * mVideoHeight / mVideoWidth;
    10            } else if ( mVideoWidth * height  < width * mVideoHeight ) {
    11                //Log.i("@@@", "image too wide, correcting");
    12                width = height * mVideoWidth / mVideoHeight;
    13            } else {
    14                //Log.i("@@@", "aspect ratio is correct: " +
    15                        //width+"/"+height+"="+
    16                        //mVideoWidth+"/"+mVideoHeight);
    17            }
    18        }*/

    19        //Log.i("@@@@@@@@@@", "setting size: " + width + 'x' + height);
    20        setMeasuredDimension(width,height);
    21    }


        二、視頻控制菜單與播放界面的層次問(wèn)題:

        看到過(guò)一些別人寫(xiě)的視頻播放器,其中有一些朋友老是簡(jiǎn)簡(jiǎn)單單的將VideoView和控制界面放在一個(gè)LinearLayout中。這樣隨著控制界面的出現(xiàn)與否,VideoView會(huì)隨之改變長(zhǎng)寬,給人的體驗(yàn)并不很好。所以,我認(rèn)為VideoView和控制界面最好不要放在同一個(gè)層次上。不要偷懶,使用一個(gè)FrameLayout或者PopupWindow就可以解決這個(gè)問(wèn)題。例如,我就簡(jiǎn)簡(jiǎn)單單地使用了PopupWindow,這個(gè)具體實(shí)現(xiàn)上,就百花爭(zhēng)鳴吧。

        三、視頻文件掃描:

        視頻文件的掃描,現(xiàn)在想來(lái)主要有兩種方式:

        第一種就是直接讀取媒體庫(kù)中的視頻文件數(shù)據(jù)庫(kù)。當(dāng)Android啟動(dòng)的時(shí)候,系統(tǒng)會(huì)自動(dòng)掃描sdcard,并為媒體文件建立(或者更新)數(shù)據(jù)庫(kù)。我們可以通過(guò)對(duì)應(yīng)的URI來(lái)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),從而得到視頻文件的列表:
      
     1private Uri videoListUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
     2
     3
     4
     5Cursor cursor = getContentResolver().query(videoListUri, new String[]{"_display_name","_data"}nullnullnull);
     6        int n = cursor.getCount();
     7        cursor.moveToFirst();
     8        LinkedList<MovieInfo> playList2 = new LinkedList<MovieInfo>();
     9        for(int i = 0 ; i != n ; ++i){
    10            MovieInfo mInfo = new MovieInfo();
    11            mInfo.displayName = cursor.getString(cursor.getColumnIndex("_display_name"));
    12            mInfo.path = cursor.getString(cursor.getColumnIndex("_data"));
    13            playList2.add(mInfo);
    14            cursor.moveToNext();
    15        }


        這種方法可能是最有效率的了,不過(guò)不知為何,媒體庫(kù)中似乎沒(méi)有掃描進(jìn)本身支持的3GP視頻格式(也可能我這里是一個(gè)特例) 。不過(guò),正是因?yàn)檫@個(gè)原因,我才想到有可能需要另外一種最基本的掃描文件系統(tǒng)的方法來(lái)掃描視頻文件。這就是文件系統(tǒng)的遍歷:

     1    private void getVideoFile(final LinkedList<MovieInfo> list,File file){
     2        
     3        file.listFiles(new FileFilter(){
     4
     5            @Override
     6            public boolean accept(File file) {
     7                // TODO Auto-generated method stub
     8                String name = file.getName();
     9                int i = name.indexOf('.');
    10                if(i != -1){
    11                    name = name.substring(i);
    12                    if(name.equalsIgnoreCase(".mp4")||name.equalsIgnoreCase(".3gp")){
    13                        
    14                        MovieInfo mi = new MovieInfo();
    15                        mi.displayName = file.getName();
    16                        mi.path = file.getAbsolutePath();
    17                        list.add(mi);
    18                        return true;
    19                    }

    20                }
    else if(file.isDirectory()){
    21                    getVideoFile(list, file);
    22                }

    23                return false;
    24            }

    25        }
    );
    26    }

        當(dāng)然,隨著Android平臺(tái)下的硬件設(shè)備越來(lái)越多,越來(lái)越強(qiáng)大。我們有理由相信,它以后將不僅僅只支持MP4和3GP格式的視頻文件,所以我們必須使用兩種方式結(jié)合的方法來(lái)獲得最大的視頻集合作為我們的視頻列表。

        四、播放過(guò)程中進(jìn)度條progress的設(shè)定:

        視頻開(kāi)始播放了,那么一個(gè)小麻煩出現(xiàn)了:什么時(shí)候設(shè)定進(jìn)度條才更有效率?我這里有一種方法供大家參考,那就是通過(guò)Handler自己給自己發(fā)消息來(lái)達(dá)到不斷設(shè)置進(jìn)度條的目的。

     1    Handler myHandler = new Handler(){
     2    
     3        @Override
     4        public void handleMessage(Message msg) {
     5            // TODO Auto-generated method stub
     6            
     7            switch(msg.what){
     8            
     9                case PROGRESS_CHANGED:
    10                    
    11                    int i = vv.getCurrentPosition();
    12                    seekBar.setProgress(i);
    13                    
    14                    i/=1000;
    15                    int minute = i/60;
    16                    int hour = minute/60;
    17                    int second = i%60;
    18                    minute %= 60;
    19                    playedTextView.setText(String.format("%02d:%02d:%02d", hour,minute,second));
    20                    
    21                    sendEmptyMessage(PROGRESS_CHANGED);
    22                    break;
    23
    24
    25
    26   
        
        當(dāng)然,這種方法,需要首先發(fā)送一個(gè)初始消息來(lái)啟動(dòng)。

        五、全屏與非全屏:

        大家都知道,一般一個(gè)Activity設(shè)置全屏的方法有兩種,一是在OnCreate中:

     1@Override   
     2public void onCreate(Bundle icicle) {   
     3    super.onCreate(icicle);   
     4       
     5    requestWindowFeature(Window.FEATURE_NO_TITLE);           
     6    Window win = getWindow();   
     7    win.setFlags(WindowManager.LayoutParams.NO_STATUS_BAR_FLAG,   
     8            WindowManager.LayoutParams.NO_STATUS_BAR_FLAG);   
     9       
    10    setContentView(R.layout.mylayout);  
    11
    12
    13

        二是在AndroidManifest.xml中:

    1<activity android:name=".MyActivity" 
    2          android:label=""
    3          android:theme="@android:style/Theme.NoTitleBar.Fullscreen">

        然而,這兩種方法都不能達(dá)到我們?cè)谝曨l播放過(guò)程中設(shè)置全屏與否的目的。因?yàn)樗鼈兌贾荒茉诔跏蓟臅r(shí)候決定全屏與否。那么我現(xiàn)在要說(shuō)的就是第三種方法:

    1getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

    1getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

        這種方法就可以在Activity運(yùn)行過(guò)程中,動(dòng)態(tài)地改變?nèi)僚c否。

        六、音量調(diào)節(jié):

        音量調(diào)節(jié)的方法其實(shí)很簡(jiǎn)單,不過(guò)有人問(wèn)到,我就在這里順便說(shuō)下:

    1        AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
    2        setIndex(am.getStreamVolume(AudioManager.STREAM_MUSIC));

        好了,就寫(xiě)這些了吧。可能這些知識(shí)有人知道,或者還有些盲點(diǎn)我沒(méi)有講到。歡迎大家與我聯(lián)系,大家一起多多討論交流,并且整個(gè)源碼都開(kāi)放出來(lái)了,大家一定可以把來(lái)龍去脈弄得一清二楚的!最后,多謝大家聽(tīng)我羅嗦,歡迎使用SeeJoPlayer,歡迎閱讀其源碼!本文也歡迎大家轉(zhuǎn)載,不過(guò)轉(zhuǎn)載請(qǐng)注明出處:http://m.tkk7.com/zh-weir/archive/2010/01/24/310617.html


             下載APK程序         下載源代碼         轉(zhuǎn)到eoeMarket發(fā)布頁(yè)



        
        

    posted on 2010-01-24 17:20 zh.weir 閱讀(61987) 評(píng)論(104)  編輯  收藏 所屬分類(lèi): Android項(xiàng)目源碼

    評(píng)論共2頁(yè): 上一頁(yè) 1 2 

    評(píng)論

    # re: Android平臺(tái)下SeeJoPlayer視頻播放器(功能介紹及源碼解析,附源碼)[未登錄](méi) 2010-01-24 18:10 L

    不知道支持的視頻格式有哪些??  回復(fù)  更多評(píng)論   

    # re: Android平臺(tái)下SeeJoPlayer視頻播放器(功能介紹及源碼解析,附源碼) 2010-01-24 18:25 zh.weir

    @L
    SeeJoPlayer采用的是系統(tǒng)默認(rèn)的解碼方式,因此對(duì)于G1來(lái)說(shuō),它應(yīng)該只支持MP4和3GP。但是如果你的系統(tǒng)本身支持更多格式,那么只要媒體庫(kù)里有的格式,它原理上都支持。  回復(fù)  更多評(píng)論   

    # re: Android平臺(tái)下SeeJoPlayer視頻播放器(功能介紹及源碼解析,附源碼) 2010-01-25 15:28 changedi

    慚愧,首先在eoeandriod看到這篇文章,來(lái)支持一下~~最近打算學(xué)習(xí)Andriod  回復(fù)  更多評(píng)論   

    # re: Android平臺(tái)下SeeJoPlayer視頻播放器(功能介紹及源碼解析,附源碼)[未登錄](méi) 2010-02-08 16:27 a

    Android1.5支持如下的媒體類(lèi)型:

    類(lèi)型
    格式
    編碼
    解碼
    詳情
    文件類(lèi)型

    Audio
    AAC LC/LTP

    Y
    單/ 雙聲道160Kpbs 的碼率,采樣4-48KHz


    3GPP(.3gp)

    MPEG-4(.mp4,.m4a)

    不支持raw AAC(.aac)

    HE-AACv1

    (AAC+)

    Y

    HE-AACv2

    ( 增強(qiáng)AAC+)

    Y

    AMR-NB
    Y
    Y
    4.75 to 12.2 kbps sampled @ 8kHz
    3GPP (.3gp)

    AMR-WB

    Y
    9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16kHz
    3GPP (.3gp)

    MP3

    Y
    Mono/Stereo 8-320Kbps constant (CBR) or variable bit-rate (VBR)
    MP3 (.mp3)

    MIDI

    Y
    MIDI Type 0 and 1. DLS Version 1 and 2. XMF and Mobile XMF. Support for ringtone formats RTTTL/RTX, OTA, and iMelody
    Type 0 and 1 (.mid, .xmf, .mxmf). Also RTTTL/RTX (.rtttl, .rtx), OTA (.ota), and iMelody (.imy)

    Ogg Vorbis

    Y

    Ogg (.ogg)

    PCM/WAVE

    Y
    8- and 16-bit linear PCM (rates up to limit of hardware)
    WAVE (.wav)

    Image
    JPEG
    Y
    Y
    Base+progressive
    JPEG(.jpg)

    GIF

    Y

    GIF(.gif)

    PNG

    Y

    PNG(.png)

    BMP

    Y

    BMP(.bmp)

    Video
    H.263
    Y
    Y

    3GPP (.3gp)


    H.264 AVC

    Y

    3GPP (.3gp) and MPEG-4 (.mp4)


    MPEG-4 SP

    Y

    3GPP (.3gp)


    T1還 額外支持了:Audio 的WMA ,Video 的WMV類(lèi)型。
      回復(fù)  更多評(píng)論   

    評(píng)論共2頁(yè): 上一頁(yè) 1 2 

    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    公告

    大家好!歡迎光臨我的 Android 技術(shù)博客!



    本博客旨在交流與 Android 操作系統(tǒng)相關(guān)的各種技術(shù)及信息。

    博客內(nèi)的文章會(huì)盡量以開(kāi)源的形式提供給大家,希望我們能相互交流,共同提高!

    有不足之處,請(qǐng)不吝賜教!

    我的郵箱:zh.weir@gmail.com
    我的新浪微博:@囧虎張建偉

     

    導(dǎo)航

    <2010年3月>
    28123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    統(tǒng)計(jì)

    留言簿(19)

    隨筆分類(lèi)(24)

    隨筆檔案(18)

    文章檔案(1)

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲国产精华液网站w| 亚洲AV无码国产精品色午友在线 | 国产在线19禁免费观看| 久久亚洲AV永久无码精品| 99久久亚洲综合精品成人网| 亚洲av成人一区二区三区观看在线 | 美女被cao免费看在线看网站| 亚洲第一页综合图片自拍| 亚洲精品高清国产一久久| 亚洲成av人无码亚洲成av人| a色毛片免费视频| 永久免费看mv网站入口| 久久精品亚洲综合一品| 羞羞的视频在线免费观看| 999久久久免费精品播放| 免费人成在线观看网站视频 | 亚洲一区二区三区在线播放 | 亚洲av永久无码精品网址| 日本高清免费观看| 国产免费久久精品| 亚洲手机中文字幕| 国产线视频精品免费观看视频| 女人18毛片a级毛片免费| 亚洲AV日韩AV高潮无码专区| 国产精品久久亚洲一区二区| 91老湿机福利免费体验| 亚洲国产一区二区三区| 在线aⅴ亚洲中文字幕| 无码精品一区二区三区免费视频| 亚洲国产专区一区| 亚洲熟妇无码一区二区三区| 久久99精品视免费看| 亚洲日本一区二区三区在线不卡| 亚洲欧美日韩一区二区三区在线| 中文字幕在线观看免费视频 | 久久99国产乱子伦精品免费| 中文字幕精品无码亚洲字| 国产精品亚洲av色欲三区| 免费看黄视频网站| 亚洲av午夜福利精品一区人妖| 美女被免费视频网站a|