开源项目之OPlayer(iPhone/iPod媒体播放)

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();
	}
}


代码简单易懂!~
学习的目标是成熟!~~




  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值