采用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 }
原文地址:https://www.cnblogs.com/yueang/p/2660968.html