您的位置:首页 > 移动开发 > Android开发

android之视频播放

2016-01-19 10:12 591 查看
工具:android studio

使用android 播放视频,一开始是使用的 vitamio 的,人家的代码写得特别好,可惜我是在android studio里调用的,哎呀,各种报错,什么R文件不识别啦,Gradle 版本的问题,无奈网上可以找到的资料实在是有限,我还傻傻的配置了NDK
的环境,可以也是没有用。

后来使用优酷的 SDK 代码,参考:/article/2308418.html

优酷:http://cloud.youku.com/app

按照介绍一步一步试咯 我下载的是精简版

android studio AIDL文件与java的关联和Eclipse是不一样的,studio需要手动在main\下新建aidl文件夹,将.aidl文件复制过来

Android Studio实现Service AIDL http://www.linuxidc.com/Linux/2015-01/111148.htm
经历了很多次的失败,什么复制文件啦,整体文件复制,包名都一样, 删掉工程重建一个,一个文件一个文件复制,drawable里的文件全部复制,可是还是会报错,

这里要说一下 直接 新建module -> android library 因为youkupalyersdk 是作为类库使用的,不需要生成apk

最后发现一个方法(亲测可行):

首先下载优酷提供的sdk http://cloud.youku.com/down

在Android Studio中新建一个工程名 xxx ,再把 YoukuPlayerOpenSDK 以模块的形式导入到新建的工程当中,接着将YoukuPlayerOpenSDK模块下的build.gradle文件中的compileSdkVersion、buildToolsVersion、minSdkVersion和targetSdkVersion都修改成跟app模块下的build.gradle相应字段一样的数据。

哎,这么简单的方法,在android studio 里直接使用开源的SDK

然后,就可以飞啦

不过优酷的有一个限制就是只可以播放优酷库里的视频,可以根据视频的网络地址,获取网页的数据得到视频的id

于是继续使用vitamio ,由于有了上面的经验,一个浪费了很长时间得到的经验,这个只要不涉及到修改别人的源码,开发就很快

首先是 到Vitamio的Github地址 https://github.com/yixia/VitamioBundle下载SDK
先是做一个读取sd卡里的视频(读取本地文件)的播放器,这个是有参考的

扫描SD卡的文件
private void scanMovieFiles() {
fileList = new ArrayList<String>();
fileListPath = new ArrayList<String>();

//要获取SD卡首先要确认SD卡是否装载
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Log.e(TAG, "SD Card not mounted.");
}
//获取sd卡上所有的文件
final File[] file = Environment.getExternalStorageDirectory().listFiles();
readFile(file);
files = fileList.toArray(new String[1]);
filesPath = fileListPath.toArray(new String[1]);
}
/*读取视频文件 会处理 fileList  和  fileListPath   */
private void readFile(final File[] file) {
for (int i = 0; (file != null) && (i < file.length); i++) {
if (file[i].isFile() && (file[i].getName().endsWith("mp4") || file[i].getName().endsWith("mkv")
|| file[i].getName().endsWith("MP4") || file[i].getName().endsWith("MKV")
|| file[i].getName().endsWith("avi") || file[i].getName().endsWith("AVI")
|| file[i].getName().endsWith("rmvb") || file[i].getName().endsWith("RMVB"))) {
fileList.add(file[i].getName());
fileListPath.add(file[i].getPath());
} else if (file[i].isDirectory()) {
//如果是文件夹,递归读取
final File[] tempFileList = new File(file[i].getAbsolutePath()).listFiles();
readFile(tempFileList);
}

}
}
还添加了播放时手势控制,双击暂定/播放,左右滑动开尽快退,上下滑动调音量

private GestureDetector gestureDetector;

/*最大声音*/
private int maxVolume;

/*当前声音*/
private int currentVolume = -1;

/**/

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

/*
* 去屏保
* */
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

videoView = (VideoView) this.findViewById(R.id.surface_view);

if (!movieUrl.isEmpty()) {
if (movieUrl.startsWith("http:")) {
videoView.setVideoURI(Uri.parse(movieUrl));
} else {
videoView.setVideoPath(movieUrl);
}
//设置成撑满全屏
videoView.setVideoLayout(VideoView.VIDEO_LAYOUT_STRETCH, 0);
videoView.setMediaController(mediaController);
videoView.requestFocus();

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setPlaybackSpeed(1.0f);
duration = mp.getDuration();
}
});

gestureDetector = new GestureDetector(this, new CustomGestureListener());
}

@Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}

switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
endGesture();
break;
}

return super.onTouchEvent(event);
}

private void endGesture() {
currentVolume = -1;

mDismissHandler.removeMessages(0);
mDismissHandler.sendEmptyMessageDelayed(0, 500);
}

private class CustomGestureListener extends GestureDetector.SimpleOnGestureListener {

/*
* 双击操作,开始和暂停
* */
/**
* 这个方法不同于onSingleTapUp,他是在GestureDetector确信用户在第一次触摸屏幕后,没有紧跟着第二次触摸屏幕,也就是不是“双击”的时候触发
* */
@Override
public boolean onDoubleTap(MotionEvent e) {
if (videoView.isPlaying()) {
videoView.pause();
} else {
videoView.start();
}

return super.onDoubleTap(e);
}

/**
* @param e1 The first down motion event that started the scrolling.
@param e2 The move motion event that triggered the current onScroll.
@param distanceX The distance along the X axis(轴) that has been scrolled since the last call to onScroll. This is NOT the distance between e1 and e2.
@param distanceY The distance along the Y axis that has been scrolled since the last call to onScroll. This is NOT the distance between e1 and e2.
无论是用手拖动view,或者是以抛的动作滚动,都会多次触发 ,这个方法在ACTION_MOVE动作发生时就会触发 参看GestureDetector的onTouchEvent方法源码
* */
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

//上下滑动
if (Math.abs(distanceY) / Math.abs(distanceX) > 3) {
float mOldY = e1.getY();
int y = (int) e2.getRawY();
Display disp = getWindowManager().getDefaultDisplay();
int windowHeight = disp.getHeight();

onVolumeSlide((mOldY - y) / windowHeight);

}

return super.onScroll(e1, e2, distanceX, distanceY);
}

/*
* 滑动操作
* */
/**
* @param e1 第1个ACTION_DOWN MotionEvent 并且只有一个
* @param e2 最后一个ACTION_MOVE MotionEvent
* @param velocityX X轴上的移动速度,像素/秒
* @param velocityY Y轴上的移动速度,像素/秒
* 这个方法发生在ACTION_UP时才会触发 参看GestureDetector的onTouchEvent方法源码
*
* */
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

currentPosition = videoView.getCurrentPosition();

/*向左滑*/
if (e1.getX() - e2.getX() > 120) {

if (currentPosition < 10000) {
currentPosition = 0;
videoView.seekTo(currentPosition);
} else {
videoView.seekTo(currentPosition - 10000);
}

} else if (e2.getX() - e1.getX() > 120) {
/*向右滑*/
if (currentPosition + 10000 > duration) {
currentPosition = duration;
videoView.seekTo(currentPosition);
} else {
videoView.seekTo(currentPosition + 10000);
}

}

return super.onFling(e1, e2, velocityX, velocityY);
}
}

/*
* 定时隐藏
* */
private Handler mDismissHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mVolumeBrightnessLayout.setVisibility(View.GONE);
}
};

/**
* 滑动改变声音大小
*/
private void onVolumeSlide(float percent) {

if (currentVolume == -1) {
currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
if (currentVolume < 0)
currentVolume = 0;

// 显示
mOperationBg.setImageResource(R.drawable.video_volumn_bg);
mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
}

int value = currentVolume + (int) (percent * maxVolume);
if (value > maxVolume) {
value = maxVolume;
} else if (value < 0) {
value = 0;
}

// 变更声音
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, value, 0);

// 变更进度条
ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
lp.width = findViewById(R.id.operation_full).getLayoutParams().width * value / maxVolume;
mOperationPercent.setLayoutParams(lp);
}
都是官方提供好的方法,直接使用它提供的VideoView和MediaController,通过手指滑动来控制音量大小则用的是FrameLayout。

播放界面布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

<io.vov.vitamio.widget.VideoView
android:id="@+id/surface_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />

<FrameLayout
android:id="@+id/operation_volume"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#00000000"
android:orientation="horizontal"
android:padding="0dip"
android:visibility="invisible">

<ImageView
android:id="@+id/operation_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/video_volumn_bg" />

<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:paddingBottom="25dip">

<ImageView
android:id="@+id/operation_full"
android:layout_width="94dip"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:src="@drawable/video_num_bg" />

<ImageView
android:id="@+id/operation_percent"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:scaleType="matrix"
android:src="@drawable/video_num_front" />
</FrameLayout>
</FrameLayout>

</RelativeLayout>
附件:优酷的源码http://download.csdn.net/detail/i_do_can/9410485

votamino的源码太大了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: