OPlayer一款用来提高你的iPhone/iPod的媒体播放能力的应用程序,支持mp3/wma/wmv/avi/rm/rmvb/mp4/3gp/mkv/mpg格式.视频文件存放于/privatear/mobile/Documents/download目录.
项目除了jni文件,共有17个目标文件!项目如图:
效果如图:
由于模拟器上缺少必要设备,所以不可以在模拟器上播放!
分析如下:
FileBusiness类:文件操作!
class SQLiteHelper extends SQLiteOpenHelper:操作数据库。
TableColumns类:播放视频的必须信息表类。
PFile类:记录视频文件信息类。
FragmentBase类:UI类,Fragment 表现 Activity 中用UI的一个行为或者一部分. 可以组合多个fragment放在一个单独的activity中来创建一个多界面区域的UI,并可以在多个activity里重用某一个fragment.把fragment 想象成一个activity的模块化区域, 有它自己的生命周期, 接收属于它的输入事件, 并且可以在activity运行期间添加和删除.
class FragmentFile extends FragmentBase implements OnItemClickListener:遍历所有文件然后读取以及定位。
class FragmentOnline extends FragmentBase implements OnItemClickListener:在线视频界面!
class MainFragmentActivity extends FragmentActivity implements OnClickListener : 主界面!
class PlayerActivity extends Activity implements OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback : 视频播放类!
class VideoPlayerActivity extends Activity implements OnCompletionListener :视频视图操作界面!
abstract class ArrayAdapter<T> extends BaseAdapter :抽象数据队列适配器!
abstract class FilterArrayAdapter<T> extends ArrayAdapter<T> :过滤字符适配器 !
VideoThumbnailUtils类:视频视图设置信息!
其它的就不介绍了!~
程序进入时会先遍历目标,检索文件信息,如下:
/** 扫描SD卡 */
private class ScanVideoTask extends AsyncTask<Void, File, ArrayList<PFile>>
{
private ProgressDialog pd;
private ArrayList<File> files = new ArrayList<File>();
@Override
protected void onPreExecute()
{
super.onPreExecute();
pd = new ProgressDialog(getActivity());
pd.setMessage("正在扫描视频文件...");
pd.show();
}
@Override
protected ArrayList<PFile> doInBackground(Void... params)
{
// ~~~ 遍历文件夹
eachAllMedias(Environment.getExternalStorageDirectory());
// ~~~ 入库
SQLiteHelper sqlite = new SQLiteHelper(getActivity());
SQLiteDatabase db = sqlite.getWritableDatabase();
try
{
db.beginTransaction();
SQLiteStatement stat = db.compileStatement("INSERT INTO files("
+ FilesColumns.COL_TITLE + ","
+ FilesColumns.COL_TITLE_PINYIN + ","
+ FilesColumns.COL_PATH + ","
+ FilesColumns.COL_LAST_ACCESS_TIME + ","
+ FilesColumns.COL_FILE_SIZE + ") VALUES(?,?,?,?,?)");
for (File f : files)
{
String name = f.getName();
int index = 1;
stat.bindString(index++, name);// title
stat.bindString(index++,
PinyinUtils.chineneToSpell(name.charAt(0) + ""));// title_pinyin
stat.bindString(index++, f.getPath());// path
stat.bindLong(index++, System.currentTimeMillis());// last_access_time
stat.bindLong(index++, f.length());
stat.execute();
}
db.setTransactionSuccessful();
} catch (BadHanyuPinyinOutputFormatCombination e)
{
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
} finally
{
db.endTransaction();
db.close();
}
// ~~~ 查询数据
return FileBusiness.getAllSortFiles(getActivity());
}
@Override
protected void onProgressUpdate(final File... values)
{
pd.setMessage(values[0].getName());
}
/** 遍历所有文件夹,查找出视频文件 */
public void eachAllMedias(File f)
{
if (f != null && f.exists() && f.isDirectory())
{
File[] files = f.listFiles();
if (files != null)
{
for (File file : f.listFiles())
{
publishProgress(file);
if (file.isDirectory())
{
eachAllMedias(file);
} else if (file.exists() && file.canRead()
&& FileUtils.isVideo(file))
{
this.files.add(file);
}
}
}
}
}
@Override
protected void onPostExecute(ArrayList<PFile> result)
{
super.onPostExecute(result);
mAdapter = new FileAdapter(getActivity(), result);
mListView.setAdapter(mAdapter);
pd.dismiss();
}
}
以下是两个主要的操作视频的类:
//播放界面
public class PlayerActivity extends Activity implements
OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener,
OnVideoSizeChangedListener, SurfaceHolder.Callback
{
private static final String TAG = "MediaPlayerDemo";
private int mVideoWidth;
private int mVideoHeight;
private MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private SurfaceHolder holder;
private String path = Environment.getExternalStorageDirectory()
+ "/Moon.mp4";
private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
@Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.mediaplayer);
mPreview = (SurfaceView) findViewById(R.id.surface);
holder = mPreview.getHolder();
holder.addCallback(this);
}
private void playVideo()
{
doCleanUp();
try
{
mMediaPlayer = new MediaPlayer(this);
mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(holder);
mMediaPlayer.prepareAsync();
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
} catch (Exception e)
{
Log.e(TAG, "error: " + e.getMessage(), e);
}
}
public void onBufferingUpdate(MediaPlayer arg0, int percent)
{
Log.d(TAG, "onBufferingUpdate percent:" + percent);
}
public void onCompletion(MediaPlayer arg0)
{
Log.d(TAG, "onCompletion called");
mMediaPlayer.release();
}
public void onVideoSizeChanged(MediaPlayer mp, int width, int height)
{
Log.v(TAG, "onVideoSizeChanged called");
if (width == 0 || height == 0)
{
Log.e(TAG, "invalid video width(" + width + ") or height(" + height
+ ")");
return;
}
mIsVideoSizeKnown = true;
mVideoWidth = width;
mVideoHeight = height;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown)
{
startVideoPlayback();
}
}
public void onPrepared(MediaPlayer mediaplayer)
{
Log.d(TAG, "onPrepared called");
mIsVideoReadyToBePlayed = true;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown)
{
startVideoPlayback();
}
}
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k)
{
Log.d(TAG, "surfaceChanged called" + i + " " + j + " " + k);
}
public void surfaceDestroyed(SurfaceHolder surfaceholder)
{
Log.d(TAG, "surfaceDestroyed called");
}
public void surfaceCreated(SurfaceHolder holder)
{
Log.d(TAG, "surfaceCreated called");
playVideo();
}
@Override
protected void onPause()
{
super.onPause();
releaseMediaPlayer();
doCleanUp();
}
@Override
protected void onDestroy()
{
super.onDestroy();
releaseMediaPlayer();
doCleanUp();
}
private void releaseMediaPlayer()
{
if (mMediaPlayer != null)
{
mMediaPlayer.release();
mMediaPlayer = null;
}
}
private void doCleanUp()
{
mVideoWidth = 0;
mVideoHeight = 0;
mIsVideoReadyToBePlayed = false;
mIsVideoSizeKnown = false;
}
private void startVideoPlayback()
{
Log.v(TAG, "startVideoPlayback");
holder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.start();
}
}
//视频视图操作界面
public class VideoPlayerActivity extends Activity implements
OnCompletionListener
{
private String path;
private VideoView mVideoView;
private View mVolumeBrightnessLayout;
private ImageView mOperationBg;
private ImageView mOperationPercent;
private AudioManager mAudioManager;
/** 最大声音 */
private int mMaxVolume;
/** 当前声音 */
private int mVolume = -1;
/** 当前亮度 */
private float mBrightness = -1f;
/** 当前缩放模式 */
private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;
private GestureDetector mGestureDetector;
private MediaController mMediaController;
@Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
Intent intent = getIntent();
path = intent.getStringExtra("path");
if (TextUtils.isEmpty(path))
path = Environment.getExternalStorageDirectory()
+ "/video/你太猖狂.flv";
else if (intent.getData() != null)
path = intent.getData().toString();
Log.e("VideoPlayerActivity", path);
setContentView(R.layout.videoview);
mVideoView = (VideoView) findViewById(R.id.surface_view);
mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);
mOperationBg = (ImageView) findViewById(R.id.operation_bg);
mOperationPercent = (ImageView) findViewById(R.id.operation_percent);
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mMaxVolume = mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
if (path.startsWith("http:"))
mVideoView.setVideoURI(Uri.parse(path));
else
mVideoView.setVideoPath(path);
//
mVideoView.setOnCompletionListener(this);
mMediaController = new MediaController(this);
mVideoView.setMediaController(mMediaController);
mVideoView.requestFocus();
// mVideoView.
// MediaPlayer
mGestureDetector = new GestureDetector(this, new MyGestureListener());
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
@Override
protected void onPause()
{
super.onPause();
mVideoView.pause();
}
@Override
protected void onResume()
{
super.onResume();
mVideoView.resume();
}
@Override
protected void onDestroy()
{
super.onDestroy();
mVideoView.stopPlayback();
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (mGestureDetector.onTouchEvent(event))
return true;
// 处理手势结束
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_UP:
endGesture();
break;
}
return super.onTouchEvent(event);
}
/** 手势结束 */
private void endGesture()
{
mVolume = -1;
mBrightness = -1f;
// 隐藏
mDismissHandler.removeMessages(0);
mDismissHandler.sendEmptyMessageDelayed(0, 500);
}
private class MyGestureListener extends SimpleOnGestureListener
{
/** 双击 */
@Override
public boolean onDoubleTap(MotionEvent e)
{
if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)
mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;
else
mLayout++;
if (mVideoView != null)
mVideoView.setVideoLayout(mLayout, 0);
return true;
}
/** 滑动 */
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY)
{
float mOldX = e1.getX(), mOldY = e1.getY();
int y = (int) e2.getRawY();
Display disp = getWindowManager().getDefaultDisplay();
int windowWidth = disp.getWidth();
int windowHeight = disp.getHeight();
if (mOldX > windowWidth * 4.0 / 5)// 右边滑动
onVolumeSlide((mOldY - y) / windowHeight);
else if (mOldX < windowWidth / 5.0)// 左边滑动
onBrightnessSlide((mOldY - y) / windowHeight);
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
/** 定时隐藏 */
private Handler mDismissHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
mVolumeBrightnessLayout.setVisibility(View.GONE);
}
};
/**
* 滑动改变声音大小
*
* @param percent
*/
private void onVolumeSlide(float percent)
{
if (mVolume == -1)
{
mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
if (mVolume < 0)
mVolume = 0;
// 显示
mOperationBg.setImageResource(R.drawable.video_volumn_bg);
mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
}
int index = (int) (percent * mMaxVolume) + mVolume;
if (index > mMaxVolume)
index = mMaxVolume;
else if (index < 0)
index = 0;
// 变更声音
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);
// 变更进度条
ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
lp.width = findViewById(R.id.operation_full).getLayoutParams().width
* index / mMaxVolume;
mOperationPercent.setLayoutParams(lp);
}
/**
* 滑动改变亮度
*
* @param percent
*/
private void onBrightnessSlide(float percent)
{
if (mBrightness < 0)
{
mBrightness = getWindow().getAttributes().screenBrightness;
if (mBrightness <= 0.00f)
mBrightness = 0.50f;
if (mBrightness < 0.01f)
mBrightness = 0.01f;
// 显示
mOperationBg.setImageResource(R.drawable.video_brightness_bg);
mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
}
WindowManager.LayoutParams lpa = getWindow().getAttributes();
lpa.screenBrightness = mBrightness + percent;
if (lpa.screenBrightness > 1.0f)
lpa.screenBrightness = 1.0f;
else if (lpa.screenBrightness < 0.01f)
lpa.screenBrightness = 0.01f;
getWindow().setAttributes(lpa);
ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);
mOperationPercent.setLayoutParams(lp);
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
if (mVideoView != null)
mVideoView.setVideoLayout(mLayout, 0);
super.onConfigurationChanged(newConfig);
}
// private void release() {
// if (isInitialized()) {
// if (Build.VERSION.SDK_INT > 13) {
// android.os.Process.killProcess(android.os.Process.myPid());
// } else {
// stopPlayer();
// vPlayer.release();
// vPlayer.releaseContext();
// }
// }
// }
@Override
public void onCompletion(MediaPlayer player)
{
finish();
}
}
学习的目标是成熟!~~