Android Video
简述
Video的播放实现,至于录制请参见《Android Camera简述》。
一、播放方式
1
)自带播放器播放
入口Action为ACTION_VIEW,Data为Uri,Type为MIME类型。
-
- private void sysPlayer(String filename) {
- Uri uri = Uri.parse(filename);
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setDataAndType(uri, "video/3gp");
- startActivity(intent);
- }
2
)VideoView
播放
VideoView组件进行播放。在《Android Camera简述》的Camera摄像样例中的预览操作即是这种方式。(例子选择VideoView播放,仍是用的同一个类==)
3
)MediaPlayer
播放
MediaPlayer进行播放控制。不再赘述了==,具体看下节例子。
二、视频播放器
1
)视频播放活动
文件浏览方式,找到3gp文件进行播放。
1)直接点击,以MediaPlayer方式播放(简单的自定义了下界面^^)
2)长按时,可选"自带播放器播放"、"VideoView播放"、"MediaPlayer播放"三种方式
2
)文件浏览器接口
定义了文件夹点击、文件点击、文件长按、错误四方法。
3
)文件列表适配器
自定义文件列表适配器。主要就是getView()内对一个Item布局的的赋值,有图片、名称、类型、大小四项。
4
)文件浏览器
自定义的文件浏览器。
1)属性资源的使用。即在attrs.xml定义的FileBrowser的属性。
不过,extName&fileImage以后缀数字不断增加的好像不好定义,仍是自定义空间方式。
2)接口事件,参见OnFileBrowserListener.java。
- public class FileBrowser extends ListView implements
- AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
-
- public static final int ERROR_ACCESS_DIR = 1;
-
-
-
-
-
-
-
- private final String namespace = "http://vaero.blog.51cto.com/";
-
-
- private String baseDir;
- private boolean backFinish;
- private int folderImageResId;
- private Map<String, Integer> fileImageResIdMap = new HashMap<String, Integer>();
- private int otherFileImageResId;
-
- private Stack<String> dirStack = new Stack<String>();
- private List<File> fileList = new ArrayList<File>();;
- private FileListAdapter fileListAdapter;
- private OnFileBrowserListener listener;
-
- public FileBrowser(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- TypedArray typedArray = context.obtainStyledAttributes(attrs,
- R.styleable.FileBrowser);
-
- baseDir = typedArray.getString(R.styleable.FileBrowser_baseDir);
- if (null == baseDir) {
- baseDir = Environment.getExternalStorageDirectory().toString();
- }
- setCurrentPath(baseDir);
-
- backFinish = typedArray.getBoolean(R.styleable.FileBrowser_backFinish,
- false);
-
- folderImageResId = typedArray.getResourceId(
- R.styleable.FileBrowser_folderImage, 0);
-
- otherFileImageResId = typedArray.getResourceId(
- R.styleable.FileBrowser_otherFileImage, 0);
-
- String extName;
- int fileImageResId;
- int index = 1;
- while (true) {
- extName = attrs.getAttributeValue(namespace, "extName" + index);
- fileImageResId = attrs.getAttributeResourceValue(namespace,
- "fileImage" + index, 0);
-
- if ("".equals(extName) || extName == null || fileImageResId == 0) {
- break;
- }
- fileImageResIdMap.put(extName, fileImageResId);
- index++;
- }
-
-
- setOnItemClickListener(this);
- setOnItemLongClickListener(this);
-
- setCurrentDirFiles();
-
- fileListAdapter = new FileListAdapter(context, fileList,
- folderImageResId, fileImageResIdMap, otherFileImageResId);
- setAdapter(fileListAdapter);
- }
-
-
- private void setCurrentPath(String dir) {
- dirStack.clear();
- String spDir = dir.charAt(0) == '/' ? dir.substring(1) : dir;
- for (String s : spDir.split("/")) {
- dirStack.push(s);
- }
- }
-
-
- private String getCurrentDir() {
- StringBuffer result = new StringBuffer();
- result.append("/");
- for (int i = 0; i < dirStack.size(); i++) {
- result.append(dirStack.get(i));
- result.append("/");
- }
- return result.toString();
- }
-
-
- private boolean setCurrentDirFiles() {
-
- File[] files = new File(getCurrentDir()).listFiles();
- if (null == files) {
- dirStack.pop();
- return false;
- }
-
- fileList.clear();
-
-
- if (!dirStack.isEmpty())
- fileList.add(null);
-
- for (File file : files) {
- fileList.add(file);
- }
-
-
- Collections.sort(fileList, new Comparator<File>() {
- @Override
- public int compare(File f1, File f2) {
- if (null == f1) {
- return -1;
- } else if (null == f2) {
- return 1;
- } else if (f1.isDirectory() && !f2.isDirectory()) {
- return -1;
- } else if (!f1.isDirectory() && f2.isDirectory()) {
- return 1;
- } else {
- return f1.toString().compareTo(f2.toString());
- }
- }
- });
-
- return true;
- }
-
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- File file = fileList.get(position);
- if (file == null) {
- dirStack.pop();
- setCurrentDirFiles();
- fileListAdapter.notifyDataSetChanged();
- if (listener != null) {
- listener.onDirItemClick(getCurrentDir());
- }
- } else if (file.isDirectory()) {
- dirStack.push(file.getName());
- if (setCurrentDirFiles()) {
- fileListAdapter.notifyDataSetChanged();
- if (listener != null) {
- listener.onDirItemClick(getCurrentDir());
- }
- } else {
- if (listener != null) {
- listener.onError(ERROR_ACCESS_DIR);
- }
- }
- } else {
- if (listener != null) {
- listener.onFileItemClick(file.getAbsolutePath());
- }
- }
-
- }
-
- @Override
- public boolean onItemLongClick(AdapterView<?> parent, View view,
- int position, long id) {
- File file = fileList.get(position);
- if (file.isFile()) {
- if (listener != null) {
- listener.onFileItemLongClick(file.getAbsolutePath());
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK && !backFinish
- && !dirStack.isEmpty()) {
- dirStack.pop();
- setCurrentDirFiles();
- fileListAdapter.notifyDataSetChanged();
- if (listener != null) {
- listener.onDirItemClick(getCurrentDir());
- }
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
-
-
- public void setOnFileBrowserListener(OnFileBrowserListener listener) {
- this.listener = listener;
- }
-
- }
5
)MediaPlayer
播放视频
MediaPlayer播放视频。控制界面很简单,描述如下:
1)暂停、播放、停止三按钮
2)进度条实时进度显示,及拖动跳转
3)进度条左侧当前时间、右侧总时间显示
ps:播放画面自适应等比例满屏
- public class VideoPlayer extends Activity implements
- MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener,
- SurfaceHolder.Callback, SeekBar.OnSeekBarChangeListener {
-
- public static final int STATUS_STOPPED = 1;
- public static final int STATUS_PAUSING = 2;
- public static final int STATUS_PLAYING = 3;
-
- private MediaPlayer mPlayer;
- private SurfaceHolder mSurfaceHolder;
-
- private SurfaceView surfaceView;
- private SeekBar seekBar;
- private TextView nowTime, totleTime;
- private LinearLayout linearLayout;
-
- private String mTimerFormat = "%02d:%02d";
-
- private final Handler mHandler = new Handler();
- private Runnable mUpdateTimer = new Runnable() {
- public void run() {
- updateTimerView();
- }
- };
-
- private String filename;
-
- private int mStatus = STATUS_STOPPED;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.video_player);
-
- surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
- seekBar = (SeekBar) findViewById(R.id.seekBar);
- seekBar.setOnSeekBarChangeListener(this);
- nowTime = (TextView) findViewById(R.id.nowTime);
- totleTime = (TextView) findViewById(R.id.totleTime);
- linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
-
-
- filename = getIntent().getStringExtra(VideoPlayerActivity.KEY_FILENAME);
-
-
- mSurfaceHolder = surfaceView.getHolder();
- mSurfaceHolder.addCallback(this);
- mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
-
-
- mPlayer = new MediaPlayer();
- mPlayer.setOnPreparedListener(this);
- mPlayer.setOnCompletionListener(this);
- try {
- mPlayer.setDataSource(filename);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
-
- public void pauseBtn(View v) {
- if (mStatus == STATUS_PLAYING) {
- mPlayer.pause();
- mStatus = STATUS_PAUSING;
- }
- }
-
-
- public void playBtn(View v) {
- if (mStatus == STATUS_PAUSING) {
- mPlayer.start();
- mStatus = STATUS_PLAYING;
- updateTimerView();
- } else {
-
- mPlayer.reset();
- try {
- mPlayer.setDataSource(filename);
- } catch (Exception e) {
- e.printStackTrace();
- }
- mPlayer.prepareAsync();
- }
- }
-
-
- public void stopBtn(View v) {
- if (mStatus != STATUS_STOPPED) {
- mPlayer.stop();
- mPlayer.reset();
- mStatus = STATUS_STOPPED;
- updateTimerView();
- }
- }
-
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- mPlayer.setDisplay(holder);
- mPlayer.prepareAsync();
- }
-
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- }
-
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- }
-
- @Override
- public void onPrepared(MediaPlayer mp) {
-
- Display display = getWindowManager().getDefaultDisplay();
- int wWidth = display.getWidth();
- int wHeight = display.getHeight();
-
- int vWidth = mPlayer.getVideoWidth();
- int vHeight = mPlayer.getVideoHeight();
-
- float wRatio = (float) vWidth / (float) wWidth;
- float hRatio = (float) vHeight / (float) wHeight;
- float ratio = Math.max(wRatio, hRatio);
- vWidth = (int) Math.ceil((float) vWidth / ratio);
- vHeight = (int) Math.ceil((float) vHeight / ratio);
-
- mSurfaceHolder.setFixedSize(vWidth, vHeight);
-
-
-
- setTimeView(totleTime, mPlayer.getDuration());
-
- mPlayer.start();
-
- mStatus = STATUS_PLAYING;
-
- updateTimerView();
- }
-
- @Override
- public void onCompletion(MediaPlayer mp) {
- mStatus = STATUS_STOPPED;
- finish();
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
-
- linearLayout
- .setVisibility(linearLayout.getVisibility() == View.VISIBLE ? View.GONE
- : View.VISIBLE);
- }
- return super.onTouchEvent(event);
- }
-
- @Override
- public void onBackPressed() {
- super.onBackPressed();
- stopBtn(null);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mPlayer.release();
- }
-
-
- private void updateTimerView() {
- if (mStatus == STATUS_PLAYING) {
- int position = mPlayer.getCurrentPosition();
- int duration = mPlayer.getDuration();
- setTimeView(nowTime, position);
- long pos = seekBar.getMax() * position / duration;
- seekBar.setProgress((int) pos);
- mHandler.postDelayed(mUpdateTimer, 1000);
- } else if (mStatus == STATUS_STOPPED) {
- nowTime.setText("00:00");
- seekBar.setProgress(0);
- }
- }
-
-
- private void setTimeView(TextView textView, int msec) {
- if (msec >= 1000 * 60 * 60) {
- textView.setText(String.format(mTimerFormat, msec / 1000 / 60 / 60,
- msec / 1000 / 60 % 60));
- } else {
- textView.setText(String.format(mTimerFormat, msec / 1000 / 60,
- msec / 1000 % 60));
- }
- }
-
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
- }
-
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
-
- }
-
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- if (mStatus == STATUS_PLAYING) {
- mPlayer.seekTo(seekBar.getProgress() * mPlayer.getDuration()
- / seekBar.getMax());
- }
- }
-
- }
三、后记
1
)扩展内容
1.1)应用资源系列之属性[Attribute]资源
1.2)RMVB软解,有兴趣的可以找找(我稍搜了下,无发现==)
2
)模块概览
2.1)Video播放
![Video播放]()
3
)运行效果
3.1)Video播放
![Video播放]()
3.2)文件浏览器
![Video播放]()
3.3)长按选择方式
![Video播放]()
3.4)自带播放器播放
![Video播放]()
3.5)VideoView播放
![Video播放]()
3.6)MediaPlayer播放
本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/834887
,如需转载请自行联系原作者