• 采用faplayer播放EPUB书中的mp4视频


    视频播放的工作终于告一段落了,由于之前对ffmpeg, vlc,流媒体这些东西完全没有接触过,所以很辛苦的查找资料,艰难的理解一点点的概念,还好,总算有了一个可行的解决方法,算是最简单的,不用对解码库有深入的了解,算是入门的方法。

     
    一、应用场景:
    EPUB书中嵌入视频,要求点击图片时能够打开相应的视频进行播放,视频的格式为mp4
     
    二、解决方法:
    1.选用播放器,最开始采用github上的开源工程 havlenapetr/ffmpeg 使用cygwin + NDK r8编译通过,在真机和模拟器上播放都正常,但是这个库有几个缺陷,最致命的是它运行需要依赖android的libjniaudio.so和libjnivideo.so两个基础库,而这两个库是与系统版本有关的,这就意味着要针对不同的版本编译不同的基础库,这给将来的应用带来了很大麻烦,另一个缺陷是大屏幕播放图像倾斜的问题,但是这个问题在网上有人已经解决了,修改onVideoSizeChangedListener的实现即可解决,具体参照havlenapetr-FFMpeg OnVideoSizeChangedListener接口的实现 这篇博文。
     
    最后找到了vlc这个解码库,它比ffmpeg还要庞大,ffmpeg只是它的一部分而已,但是它的好处是各种android版本都支持的比较好,所以就采用它了。在ubuntu 10 + ruby 1.9.2 + NDK r5c下编译通过,播放本地视频一切正常。代码下载地址 https://github.com/tewilove/faplayer
     
    完成了这一步,整个工作就完成了一半,另外一半是如何播放EPUB书中的mp4视频? 这里边有两个问题:
     
    1. 我们知道,EPUB其实就是一个zip文件,那么为了减少缓冲时间,最好的方式是把mp4不压缩存储在zip文件中,播放时直接把文件指针seek到mp4开始的位置开始加载,用播放本地文件的方式来解码,但是看了faplayer提供的接口后我放弃了,faplayer提供了类似android自带的MediaPlayer的接口,数据加载只有一个setDataSource(String path)的接口。完全没有办法加载文件指针,所以我们退一步,把mp4缓存到本地来播放,这样的话为了减少播放前的等待时间,我们不能等到Mp4加载全部完成后再来播放,只能边缓冲边播放,这就带来了第二个问题:
     
    2.我们知道,mp4的结构信息存储在一个叫moov的box中,我们至少要等到moov这个box被加载后(当然还得有一部分真实的音视频数据也得被加载)后,才能正常进行播放,而真实的mp4中,有很多是吧moov放置在文件的尾部的,我猜测是便于生成数据,避免产生moov box对后面数据的偏移产生影响。这就需要预先对mp4进行调整(预先我指的是在制作EPUB书的时候),在参考http://blog.zhourunsheng.com上的一篇博文后,我找到了qt-faststart 这个工具,它可以把moov box调整到文件的前部,后来我找到了一个更好的工具,我们在后面再说。
    调整完moov后还有一个问题:moov中记录了mp4有多少个track,track中记录的是真实的音视频数据存储的位置,而真实数据存储在mdat中,而且经常是音频,视频分开放置的,而且有可能相隔的比较远,这样的话就会出现一个问题:在播放的时候音频或是视频数据被丢掉了,要避免这个问题,我们需要对mp4做一个处理,这个处理就叫做"流化",经过搜索,我找到了一个很好的工具,那就是VLC Media Player 下载地址 http://www.videolan.org/vlc/download-windows.html 它提供了很好的流化视频的功能,在流化的时候会把moov提到文件前面去,所以它比qt-faststart这个工具要强很多,完成这个后我们的播放就基本上没有技术难题了
     
    好了,说了这么多,放出示例代码,代码参照faplayer:
      1 public class VideoPlayerActivity extends Activity implements
      2         AbsMediaPlayer.OnBufferingUpdateListener,
      3         AbsMediaPlayer.OnCompletionListener, AbsMediaPlayer.OnErrorListener,
      4         AbsMediaPlayer.OnInfoListener, AbsMediaPlayer.OnPreparedListener,
      5         AbsMediaPlayer.OnProgressUpdateListener,
      6         AbsMediaPlayer.OnVideoSizeChangedListener, OnTouchListener,
      7         OnClickListener, OnSeekBarChangeListener {
      8 
      9     static final String LOGTAG = "DANMAKU-PlayerActivity";
     10 
     11     private static final int SURFACE_NONE = 0;
     12     private static final int SURFACE_FILL = 1;
     13     private static final int SURFACE_ORIG = 2;
     14     private static final int SURFACE_4_3 = 3;
     15     private static final int SURFACE_16_9 = 4;
     16     private static final int SURFACE_16_10 = 5;
     17     private static final int SURFACE_MAX = 6;
     18 
     19     private static final int MEDIA_PLAYER_BUFFERING_UPDATE = 0x4001;
     20     private static final int MEDIA_PLAYER_COMPLETION = 0x4002;
     21     private static final int MEDIA_PLAYER_ERROR = 0x4003;
     22     private static final int MEDIA_PLAYER_INFO = 0x4004;
     23     private static final int MEDIA_PLAYER_PREPARED = 0x4005;
     24     private static final int MEDIA_PLAYER_PROGRESS_UPDATE = 0x4006;
     25     private static final int MEDIA_PLAYER_VIDEO_SIZE_CHANGED = 0x4007;
     26 
     27     private static final int VIDEO_STATE_UPDATE = 0x4008;
     28     private static final int VIDEO_CACHE_READY = 0x4009;
     29     private static final int VIDEO_CACHE_UPDATE = 0x400A;
     30     private static final int VIDEO_CACHE_FINISH = 0x400B;
     31 
     32     public static final String REMOTE_URL = "url";
     33 
     34     private static final int READY_BUFFER_LENGTH = 0;
     35 
     36     private static final int CACHE_BUFFER_LENGTH = 0;
     37 
     38     /* the media player */
     39     private AbsMediaPlayer mMediaPlayer = null;
     40 
     41     /* GUI evnet handler */
     42     private Handler mEventHandler;
     43 
     44     /* player misc */
     45     private ProgressBar mProgressBarPreparing;
     46 
     47     /* player controls */
     48     private TextView mTextViewTime;
     49     private SeekBar mSeekBarProgress;
     50     private TextView mTextViewLength;
     51     private ImageButton mImageButtonToggleMessage;
     52     private ImageButton mImageButtonSwitchAudio;
     53     private ImageButton mImageButtonSwitchSubtitle;
     54     private ImageButton mImageButtonPrevious;
     55     private ImageButton mImageButtonTogglePlay;
     56     private ImageButton mImageButtonNext;
     57     private ImageButton mImageButtonSwitchAspectRatio;
     58 
     59     private LinearLayout mLinearLayoutControlBar;
     60 
     61     /* player video */
     62     private SurfaceView mSurfaceViewVlc;
     63     private SurfaceHolder mSurfaceHolderVlc;
     64 
     65     /* misc */
     66     private boolean mMediaPlayerLoaded = false;
     67     private boolean mMediaPlayerStarted = false;
     68 
     69     /* misc */
     70     private int mTime = -1;
     71     private int mLength = -1;
     72     private boolean mCanSeek = true;
     73     private int mAspectRatio = 0;
     74 
     75     private int mAudioTrackIndex = 0;
     76     private int mAudioTrackCount = 0;
     77     private int mSubtitleTrackIndex = 0;
     78     private int mSubtitleTrackCount = 0;
     79 
     80     private String localUri = null;
     81     private String remoteUrl = null;
     82     private long mediaLength = 0;
     83 
     84     private int readSize;
     85     private boolean isReady;
     86     private int errorCount;
     87 
     88     protected boolean isError;
     89 
     90     protected int curPosition;
     91 
     92     private String cacheFilePath;
     93 
     94     protected void initializeEvents() {
     95         mEventHandler = new Handler() {
     96             public void handleMessage(Message msg) {
     97                 switch (msg.what) {
     98                 case MEDIA_PLAYER_BUFFERING_UPDATE: {
     99                     if (mMediaPlayerLoaded) {
    100                         mProgressBarPreparing
    101                                 .setVisibility(msg.arg1 < 100 ? View.VISIBLE
    102                                         : View.GONE);
    103                     }
    104                 }
    105                     break;
    106                 case MEDIA_PLAYER_COMPLETION: {
    107                     curPosition = 0;
    108                     mMediaPlayer.pause();
    109                 }
    110                     break;
    111                 case MEDIA_PLAYER_ERROR: {
    112                     mMediaPlayerLoaded = true;
    113                     isError = true;
    114                     errorCount++;
    115                     mMediaPlayer.pause();
    116                     mProgressBarPreparing.setVisibility(View.VISIBLE);
    117                 }
    118                     break;
    119                 case MEDIA_PLAYER_INFO: {
    120                     if (msg.arg1 == MediaPlayer.MEDIA_INFO_NOT_SEEKABLE) {
    121                         mCanSeek = false;
    122                     }
    123                 }
    124                     break;
    125                 case MEDIA_PLAYER_PREPARED: {
    126                     mProgressBarPreparing.setVisibility(View.GONE);
    127                     mMediaPlayerLoaded = true;
    128                     mMediaPlayer.seekTo(curPosition);
    129                     startMediaPlayer();
    130                 }
    131                     break;
    132                 case MEDIA_PLAYER_PROGRESS_UPDATE: {
    133                     if (mMediaPlayer != null) {
    134                         int length = msg.arg2;
    135                         if (length >= 0) {
    136                             mLength = length;
    137                             mTextViewLength.setText(SystemUtility
    138                                     .getTimeString(mLength));
    139                             mSeekBarProgress.setMax(mLength);
    140                         }
    141                         int time = msg.arg1;
    142                         if (time >= 0) {
    143                             mTime = time;
    144                             mTextViewTime.setText(SystemUtility
    145                                     .getTimeString(mTime));
    146                             mSeekBarProgress.setProgress(mTime);
    147                         }
    148                     }
    149                 }
    150                     break;
    151                 case MEDIA_PLAYER_VIDEO_SIZE_CHANGED: {
    152                     AbsMediaPlayer player = (AbsMediaPlayer) msg.obj;
    153                     SurfaceView surface = mSurfaceViewVlc;
    154                     int ar = mAspectRatio;
    155                     changeSurfaceSize(player, surface, ar);
    156                 }
    157                     break;
    158 
    159                 case VIDEO_STATE_UPDATE: // 缓冲启动
    160                     break;
    161                 case VIDEO_CACHE_READY: { // 缓冲完成最低限度
    162                     isReady = true;
    163                     mMediaPlayer.setDataSource(localUri);
    164                     mMediaPlayer.prepareAsync();
    165                 }
    166                     break;
    167                 case VIDEO_CACHE_UPDATE: { // 缓冲加载
    168                     if (isError) {
    169                         mMediaPlayer.setDataSource(localUri);
    170                         mMediaPlayer.prepareAsync();
    171                         isError = false;
    172                     }
    173                 }
    174                     break;
    175                 case VIDEO_CACHE_FINISH: { // 缓冲结束
    176                     if (isError) {
    177                         mMediaPlayer.setDataSource(localUri);
    178                         mMediaPlayer.prepareAsync();
    179                         isError = false;
    180                     }
    181                 }
    182                     break;
    183                 default:
    184                     break;
    185                 }
    186                 
    187                 super.handleMessage(msg);
    188             }
    189         };
    190     }
    191 
    192     protected void initializeControls() {
    193         /* SufaceView used by VLC is a normal surface */
    194         mSurfaceViewVlc = (SurfaceView) findViewById(R.id.player_surface_vlc);
    195         mSurfaceHolderVlc = mSurfaceViewVlc.getHolder();
    196         mSurfaceHolderVlc.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
    197         mSurfaceHolderVlc.addCallback(new SurfaceHolder.Callback() {
    198             @Override
    199             public void surfaceCreated(SurfaceHolder holder) {
    200                 createMediaPlayer(false, localUri, mSurfaceHolderVlc);
    201             }
    202 
    203             @Override
    204             public void surfaceChanged(SurfaceHolder holder, int format,
    205                     int width, int height) {
    206                 mMediaPlayer.setDisplay(holder);
    207             }
    208 
    209             @Override
    210             public void surfaceDestroyed(SurfaceHolder holder) {
    211                 destroyMediaPlayer(false);
    212             }
    213 
    214         });
    215         mSurfaceViewVlc.setOnTouchListener(this);
    216 
    217         mTextViewTime = (TextView) findViewById(R.id.player_text_position);
    218         mSeekBarProgress = (SeekBar) findViewById(R.id.player_seekbar_progress);
    219         mSeekBarProgress.setOnSeekBarChangeListener(this);
    220         mTextViewLength = (TextView) findViewById(R.id.player_text_length);
    221         mImageButtonToggleMessage = (ImageButton) findViewById(R.id.player_button_toggle_message);
    222         mImageButtonToggleMessage.setOnClickListener(this);
    223         mImageButtonSwitchAudio = (ImageButton) findViewById(R.id.player_button_switch_audio);
    224         mImageButtonSwitchAudio.setOnClickListener(this);
    225         mImageButtonSwitchSubtitle = (ImageButton) findViewById(R.id.player_button_switch_subtitle);
    226         mImageButtonSwitchSubtitle.setOnClickListener(this);
    227         mImageButtonPrevious = (ImageButton) findViewById(R.id.player_button_previous);
    228         mImageButtonPrevious.setOnClickListener(this);
    229         mImageButtonTogglePlay = (ImageButton) findViewById(R.id.player_button_toggle_play);
    230         mImageButtonTogglePlay.setOnClickListener(this);
    231         mImageButtonNext = (ImageButton) findViewById(R.id.player_button_next);
    232         mImageButtonNext.setOnClickListener(this);
    233         mImageButtonSwitchAspectRatio = (ImageButton) findViewById(R.id.player_button_switch_aspect_ratio);
    234         mImageButtonSwitchAspectRatio.setOnClickListener(this);
    235 
    236         mLinearLayoutControlBar = (LinearLayout) findViewById(R.id.player_control_bar);
    237 
    238         mProgressBarPreparing = (ProgressBar) findViewById(R.id.player_prepairing);
    239     }
    240 
    241     protected void initializeData() throws IOException {
    242         Intent intent = getIntent();
    243         remoteUrl = intent.getStringExtra(REMOTE_URL);
    244         if (remoteUrl == null) {
    245             finish();
    246         }
    247 
    248         if (remoteUrl.startsWith("file:")) {
    249             localUri = remoteUrl;
    250         } else {
    251             cacheFilePath = App.getInstance().getMediaCachePath() + "cache.mp4";
    252             File cacheFile = new File(cacheFilePath);
    253             if (cacheFile.exists()) {
    254                 cacheFile.delete();
    255             }
    256 
    257             cacheFile.getParentFile().mkdirs();
    258             cacheFile.createNewFile();
    259             localUri = Uri.fromFile(cacheFile).toString();
    260 
    261             new Thread(new Runnable() {
    262 
    263                 @Override
    264                 public void run() {
    265                     startBufferData();
    266                 }
    267             }).start();
    268         }
    269     }
    270 
    271     private void startBufferData() {
    272         InputStream is = null;
    273         FileOutputStream out = null;
    274         try {
    275             out = new FileOutputStream(cacheFilePath);
    276             if (URLUtil.isNetworkUrl(remoteUrl)) {
    277                 URL url = new URL(remoteUrl);
    278                 HttpURLConnection httpConnection = (HttpURLConnection) url
    279                         .openConnection();
    280                 is = httpConnection.getInputStream();
    281                 mediaLength = httpConnection.getContentLength();
    282             } else {
    283                 // TODO fix this, very very bad idea
    284                 Book book = App.getInstance().getBook();
    285                 is = book.getEntryInputStream(remoteUrl);
    286                 mediaLength = book.getEntrySize(remoteUrl);
    287             }
    288 
    289             if (is == null || mediaLength == -1) {
    290                 return;
    291             }
    292             
    293             byte[] buf = new byte[4 * 1024];
    294             int size = 0;
    295             int lastReadSize = 0;
    296 
    297             mEventHandler.sendEmptyMessage(VIDEO_STATE_UPDATE);
    298 
    299             while ((size = is.read(buf)) != -1) {
    300                 try {
    301                     out.write(buf, 0, size);
    302                     readSize += size;
    303                 } catch (IOException e) {
    304                     e.printStackTrace();
    305                 }
    306 
    307                 if (!isReady) {
    308                     if (readSize - lastReadSize > READY_BUFFER_LENGTH
    309                             || readSize - lastReadSize == mediaLength) {
    310                         lastReadSize = readSize;
    311                         int timeCount = 0;
    312                         while (timeCount < 10) {
    313                             if (mMediaPlayer != null) {
    314                                 mEventHandler
    315                                         .sendEmptyMessage(VIDEO_CACHE_READY);
    316                                 break;
    317                             } else {
    318                                 try {
    319                                     Thread.sleep(1000);
    320                                 } catch (InterruptedException e) {
    321                                     // TODO Auto-generated catch block
    322                                     e.printStackTrace();
    323                                 }
    324                                 timeCount++;
    325                             }
    326                         }
    327                     }
    328                 } else {
    329                     if (readSize - lastReadSize > CACHE_BUFFER_LENGTH
    330                             * (errorCount + 1)) {
    331                         lastReadSize = readSize;
    332                         mEventHandler.sendEmptyMessage(VIDEO_CACHE_UPDATE);
    333                     }
    334                 }
    335             }
    336 
    337             mEventHandler.sendEmptyMessage(VIDEO_CACHE_FINISH);
    338         } catch (IOException e) {
    339             e.printStackTrace();
    340         } finally {
    341             if (out != null) {
    342                 try {
    343                     out.close();
    344                 } catch (IOException e) {
    345                     // TODO Auto-generated catch block
    346                     e.printStackTrace();
    347                 }
    348             }
    349 
    350             if (is != null) {
    351                 try {
    352                     is.close();
    353                 } catch (IOException e) {
    354                     // TODO Auto-generated catch block
    355                     e.printStackTrace();
    356                 }
    357             }
    358         }
    359     }
    360 
    361     protected void resetMediaPlayer() {
    362         int resource = -1;
    363         /* initial status */
    364         mMediaPlayerLoaded = false;
    365         mTime = -1;
    366         mLength = -1;
    367         mCanSeek = true;
    368         mAspectRatio = 0;
    369         /* */
    370         mImageButtonToggleMessage.setVisibility(View.GONE);
    371         mImageButtonSwitchAudio.setVisibility(View.GONE);
    372         mImageButtonSwitchSubtitle.setVisibility(View.GONE);
    373         mImageButtonPrevious.setVisibility(View.GONE);
    374         mImageButtonTogglePlay.setVisibility(View.VISIBLE);
    375         resource = SystemUtility.getDrawableId("btn_play_0");
    376         mImageButtonTogglePlay.setBackgroundResource(resource);
    377         mImageButtonNext.setVisibility(View.GONE);
    378         mImageButtonSwitchAspectRatio.setVisibility(View.VISIBLE);
    379         resource = SystemUtility.getDrawableId("btn_aspect_ratio_0");
    380         mImageButtonSwitchAspectRatio.setBackgroundResource(resource);
    381         /* */
    382         mLinearLayoutControlBar.setVisibility(View.GONE);
    383     }
    384 
    385     protected void selectMediaPlayer(String uri, boolean forceVlc) {
    386         /* TODO: do this through configuration */
    387         boolean useDefault = true;
    388         int indexOfDot = uri.lastIndexOf('.');
    389         if (indexOfDot != -1) {
    390             String extension = uri.substring(indexOfDot).toLowerCase();
    391             if (extension.compareTo(".flv") == 0
    392                     || extension.compareTo(".hlv") == 0
    393                     || extension.compareTo(".m3u8") == 0
    394                     || extension.compareTo(".mkv") == 0
    395                     || extension.compareTo(".rm") == 0
    396                     || extension.compareTo(".rmvb") == 0) {
    397                 useDefault = false;
    398             }
    399         }
    400         if (forceVlc) {
    401             useDefault = false;
    402         }
    403         mSurfaceViewVlc.setVisibility(useDefault ? View.GONE : View.VISIBLE);
    404     }
    405 
    406     protected void createMediaPlayer(boolean useDefault, String uri,
    407             SurfaceHolder holder) {
    408         Log.d(LOGTAG, "createMediaPlayer() " + uri);
    409         /* */
    410         resetMediaPlayer();
    411         /* */
    412         mMediaPlayer = AbsMediaPlayer.getMediaPlayer(useDefault/* false */);
    413         mMediaPlayer.setOnBufferingUpdateListener(this);
    414         mMediaPlayer.setOnCompletionListener(this);
    415         mMediaPlayer.setOnErrorListener(this);
    416         mMediaPlayer.setOnInfoListener(this);
    417         mMediaPlayer.setOnPreparedListener(this);
    418         mMediaPlayer.setOnProgressUpdateListener(this);
    419         mMediaPlayer.setOnVideoSizeChangedListener(this);
    420         mMediaPlayer.reset();
    421         mMediaPlayer.setDisplay(holder);
    422         mMediaPlayer.setDataSource(uri);
    423         mMediaPlayer.prepareAsync();
    424     }
    425 
    426     protected void destroyMediaPlayer(boolean isDefault) {
    427         if (!isDefault) {
    428             mMediaPlayer.setDisplay(null);
    429             mMediaPlayer.release();
    430             mMediaPlayer = null;
    431         }
    432     }
    433 
    434     protected void startMediaPlayer() {
    435         if (mMediaPlayerStarted || !mMediaPlayerLoaded)
    436             return;
    437         if (mMediaPlayer != null) {
    438             mMediaPlayer.start();
    439             mMediaPlayerStarted = true;
    440         }
    441     }
    442 
    443     protected void changeSurfaceSize(AbsMediaPlayer player,
    444             SurfaceView surface, int ar) {
    445         int videoWidth = player.getVideoWidth();
    446         int videoHeight = player.getVideoHeight();
    447         if (videoWidth <= 0 || videoHeight <= 0) {
    448             return;
    449         }
    450         SurfaceHolder holder = surface.getHolder();
    451         holder.setFixedSize(videoWidth, videoHeight);
    452         int displayWidth = getWindowManager().getDefaultDisplay().getWidth();
    453         int displayHeight = getWindowManager().getDefaultDisplay().getHeight();
    454         int targetWidth = -1;
    455         int targetHeight = -1;
    456         switch (ar) {
    457         case SURFACE_NONE: {
    458             targetWidth = videoWidth;
    459             targetHeight = videoHeight;
    460             break;
    461         }
    462         case SURFACE_FILL: {
    463             break;
    464         }
    465         case SURFACE_ORIG: {
    466             displayWidth = videoWidth;
    467             displayHeight = videoHeight;
    468             break;
    469         }
    470         case SURFACE_4_3: {
    471             targetWidth = 4;
    472             targetHeight = 3;
    473             break;
    474         }
    475         case SURFACE_16_9: {
    476             targetWidth = 16;
    477             targetHeight = 9;
    478             break;
    479         }
    480         case SURFACE_16_10: {
    481             targetWidth = 16;
    482             targetHeight = 10;
    483             break;
    484         }
    485         default:
    486             break;
    487         }
    488         if (targetWidth > 0 && targetHeight > 0) {
    489             double ard = (double) displayWidth / (double) displayHeight;
    490             double art = (double) targetWidth / (double) targetHeight;
    491             if (ard > art) {
    492                 displayWidth = displayHeight * targetWidth / targetHeight;
    493             } else {
    494                 displayHeight = displayWidth * targetHeight / targetWidth;
    495             }
    496         }
    497         LayoutParams lp = surface.getLayoutParams();
    498         lp.width = displayWidth;
    499         lp.height = displayHeight;
    500         surface.setLayoutParams(lp);
    501         surface.invalidate();
    502     }
    503 
    504     @Override
    505     public void onCreate(Bundle savedInstanceState) {
    506         super.onCreate(savedInstanceState);
    507         initializeEvents();
    508         setContentView(R.layout.player);
    509         initializeControls();
    510         mProgressBarPreparing.setVisibility(View.VISIBLE);
    511         try {
    512             initializeData();
    513         } catch (IOException e) {
    514             e.printStackTrace();
    515             finish();
    516         }
    517 
    518         if (localUri == null) {
    519             finish();
    520         }
    521         selectMediaPlayer(localUri, true);
    522     }
    523 
    524     @Override
    525     public void onDestroy() {
    526         super.onDestroy();
    527     }
    528 
    529     @Override
    530     public void onStart() {
    531         super.onStart();
    532     }
    533 
    534     @Override
    535     public void onStop() {
    536         super.onStop();
    537         if (mMediaPlayer != null) {
    538             mMediaPlayer.pause();
    539         }
    540     }
    541 
    542     @Override
    543     public boolean onTouch(View v, MotionEvent event) {
    544         if (!mMediaPlayerLoaded) {
    545             return true;
    546         }
    547         int action = event.getAction();
    548         if (action == MotionEvent.ACTION_DOWN) {
    549             int visibility = mLinearLayoutControlBar.getVisibility();
    550             if (visibility != View.VISIBLE) {
    551                 mLinearLayoutControlBar.setVisibility(View.VISIBLE);
    552             } else {
    553                 mLinearLayoutControlBar.setVisibility(View.GONE);
    554             }
    555             return true;
    556         }
    557         return false;
    558     }
    559 
    560     @Override
    561     public void onClick(View v) {
    562         if (!mMediaPlayerLoaded)
    563             return;
    564         int id = v.getId();
    565         switch (id) {
    566         case R.id.player_button_switch_audio: {
    567 
    568             break;
    569         }
    570         case R.id.player_button_switch_subtitle: {
    571 
    572             break;
    573         }
    574         case R.id.player_button_previous: {
    575 
    576             break;
    577         }
    578         case R.id.player_button_toggle_play: {
    579             boolean playing = false;
    580             if (mMediaPlayer != null)
    581                 playing = mMediaPlayer.isPlaying();
    582             if (playing) {
    583                 if (mMediaPlayer != null)
    584                     mMediaPlayer.pause();
    585             } else {
    586                 if (mMediaPlayer != null)
    587                     mMediaPlayer.start();
    588             }
    589             String name = String.format("btn_play_%d", !playing ? 1 : 0);
    590             int resouce = SystemUtility.getDrawableId(name);
    591             mImageButtonTogglePlay.setBackgroundResource(resouce);
    592             break;
    593         }
    594         case R.id.player_button_next: {
    595             break;
    596         }
    597         case R.id.player_button_switch_aspect_ratio: {
    598             mAspectRatio = (mAspectRatio + 1) % SURFACE_MAX;
    599             if (mMediaPlayer != null)
    600                 changeSurfaceSize(mMediaPlayer, mSurfaceViewVlc, mAspectRatio);
    601             String name = String.format("btn_aspect_ratio_%d", mAspectRatio);
    602             int resource = SystemUtility.getDrawableId(name);
    603             mImageButtonSwitchAspectRatio.setBackgroundResource(resource);
    604             break;
    605         }
    606         default:
    607             break;
    608         }
    609     }
    610 
    611     @Override
    612     public void onProgressChanged(SeekBar seekBar, int progress,
    613             boolean fromUser) {
    614         /* not used */
    615     }
    616 
    617     @Override
    618     public void onStartTrackingTouch(SeekBar seekBar) {
    619         /* not used */
    620     }
    621 
    622     @Override
    623     public void onStopTrackingTouch(SeekBar seekBar) {
    624         if (!mMediaPlayerLoaded)
    625             return;
    626         int id = seekBar.getId();
    627         switch (id) {
    628         case R.id.player_seekbar_progress: {
    629             if (mCanSeek && mLength > 0) {
    630                 int position = seekBar.getProgress();
    631                 if (mMediaPlayer != null)
    632                     mMediaPlayer.seekTo(position);
    633             }
    634             break;
    635         }
    636         default:
    637             break;
    638         }
    639     }
    640 
    641     @Override
    642     public void onBufferingUpdate(AbsMediaPlayer mp, int percent) {
    643         Message msg = new Message();
    644         msg.obj = mp;
    645         msg.what = MEDIA_PLAYER_BUFFERING_UPDATE;
    646         msg.arg1 = percent;
    647         mEventHandler.sendMessage(msg);
    648     }
    649 
    650     @Override
    651     public void onCompletion(AbsMediaPlayer mp) {
    652         Message msg = new Message();
    653         msg.obj = mp;
    654         msg.what = MEDIA_PLAYER_COMPLETION;
    655         mEventHandler.sendMessage(msg);
    656     }
    657 
    658     @Override
    659     public boolean onError(AbsMediaPlayer mp, int what, int extra) {
    660         Message msg = new Message();
    661         msg.obj = mp;
    662         msg.what = MEDIA_PLAYER_ERROR;
    663         msg.arg1 = what;
    664         msg.arg2 = extra;
    665         mEventHandler.sendMessage(msg);
    666         return true;
    667     }
    668 
    669     @Override
    670     public boolean onInfo(AbsMediaPlayer mp, int what, int extra) {
    671         Message msg = new Message();
    672         msg.obj = mp;
    673         msg.what = MEDIA_PLAYER_INFO;
    674         msg.arg1 = what;
    675         msg.arg2 = extra;
    676         mEventHandler.sendMessage(msg);
    677         return true;
    678     }
    679 
    680     @Override
    681     public void onPrepared(AbsMediaPlayer mp) {
    682         Message msg = new Message();
    683         msg.obj = mp;
    684         msg.what = MEDIA_PLAYER_PREPARED;
    685         mEventHandler.sendMessage(msg);
    686     }
    687 
    688     @Override
    689     public void onProgressUpdate(AbsMediaPlayer mp, int time, int length) {
    690         Message msg = new Message();
    691         msg.obj = mp;
    692         msg.what = MEDIA_PLAYER_PROGRESS_UPDATE;
    693         msg.arg1 = time;
    694         msg.arg2 = length;
    695         mEventHandler.sendMessage(msg);
    696     }
    697 
    698     @Override
    699     public void onVideoSizeChangedListener(AbsMediaPlayer mp, int width,
    700             int height) {
    701         Message msg = new Message();
    702         msg.obj = mp;
    703         msg.what = MEDIA_PLAYER_VIDEO_SIZE_CHANGED;
    704         msg.arg1 = width;
    705         msg.arg2 = height;
    706         mEventHandler.sendMessage(msg);
    707     }
    708 }
  • 相关阅读:
    实用Javascript调试技巧
    fetch的常见问题及其解决办法
    为什么重复的GET请求变慢了?
    JavaScript深入浅出第4课:V8引擎是如何工作的?
    一步一步搭建前端监控系统:如何定位前端线上问题?
    如何使用 Set 来提高JS代码的性能
    详解Vue的slot新用法
    详解Vue响应式原理
    BeautyWe.js 一套专注于微信小程序的开发范式
    await Task.Yield()和await Task.CompletedTask有什么不同
  • 原文地址:https://www.cnblogs.com/yueang/p/2660968.html
Copyright © 2020-2023  润新知