1.首先在mainifast中注册权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
2.获取本地视频
public class MainActivity extends AppCompatActivity implements MyVideoAdapter.PlayCallback{ private static final int MSG_WHAT_VIDEOS = 10; private String filePath; private MyVideoAdapter adatper; private ListView lvVideo; // private static final String TAG = "test"; public static List<LocalVideo> videos = new ArrayList<>(); private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case MSG_WHAT_VIDEOS: videos = (List<LocalVideo>) msg.obj; adatper.setVideos(videos); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); getJurisdiction(); getLocalVideo(); } private void initData() { lvVideo = ((ListView) findViewById(R.id.lvVideo)); adatper = new MyVideoAdapter(this,videos); lvVideo.setAdapter(adatper); adatper.setCallback(this); } /** * 增加动态权限 */ private void getJurisdiction() { if (ContextCompat.checkSelfPermission( MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(MainActivity.this,new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},1); } ; if (ContextCompat.checkSelfPermission( MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(MainActivity.this,new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},1); } } /** * 异步获取本地视频信息 */ private void getLocalVideo() { filePath = Environment.getExternalStorageDirectory().getAbsolutePath(); new Thread(new Runnable() { @Override public void run() { List<LocalVideo> videos = MediaUtil.getLocalVideo(MainActivity.this,filePath); Message msg = handler.obtainMessage(); msg.what = MSG_WHAT_VIDEOS; msg.obj = videos; handler.sendMessage(msg); } }).start(); } @Override public void playVideo(int positon) { Intent intent = new Intent(MainActivity.this, PlayActivity.class); intent.putExtra("position",positon); startActivity(intent); // Toast.makeText(MainActivity.this, "我点击了第" + positon, Toast.LENGTH_SHORT).show(); } }
3.使用mediaPlayer + surfaceView播放视频
public class PlayActivity extends AppCompatActivity { // private static final String TAG = "playActivity"; private static final float WIDGET = 100; private LocalVideo video; private String filePath; private TextView tvPlayPauseVideo; private TextView tvCurrentTimeVideo; private TextView tvTotalTimeVideo; private TextView tvPause; private SeekBar seekbarVideo; private MediaPlayer mediaPlayer; private boolean activityStopped = false; private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; private RelativeLayout rlRoot; private TextView tvSound; private RelativeLayout rlControl; private int index = 0; private int currentVolume; private AudioManager manager; private boolean flag = false; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); } }; private int duration; private int currentPosition; private int screenWidth; private TextView tvBack; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_play); getData(); initControle(); initMedia(); playVideo(); playOrPause(); screenSlideListener(); back(); } private void back() { tvBack.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { finish(); } }); } private void screenSlideListener() { //获取屏幕的宽度 screenWidth = getResources().getDisplayMetrics().widthPixels; surfaceView.setOnTouchListener(new View.OnTouchListener() { private float downY; private float downX; @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: downX = motionEvent.getX(); downY = motionEvent.getY(); break; case MotionEvent.ACTION_MOVE: float distanceX = motionEvent.getX() - downX; float distanceY = motionEvent.getY() - downY; if (downX > screenWidth -500 && Math.abs(distanceX) < 50 && distanceY > WIDGET) { setVolume(false); } else if (downX > screenWidth - 500 && Math.abs(distanceX) < 50 && distanceY < -WIDGET) { setVolume(true); } if (Math.abs(distanceY) < 50 && distanceX > WIDGET) { setSpeedReverse(true); downX = motionEvent.getX(); downY = motionEvent.getY(); } else if (Math.abs(distanceY) < 50 && distanceX < -WIDGET) { setSpeedReverse(false); downX = motionEvent.getX(); downY = motionEvent.getY(); } break; } return true; } }); } private void playOrPause() { tvPlayPauseVideo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { MediaUtil.playOrPause(PlayActivity.this); setPlayOrPause(); } }); tvPause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { MediaUtil.playOrPause(PlayActivity.this); setPlayOrPause(); } }); } private void initControle() { tvBack = ((TextView) findViewById(R.id.tvBack)); surfaceView = ((SurfaceView) findViewById(R.id.surfaceView)); seekbarVideo = ((SeekBar) findViewById(R.id.seekbarVideo)); tvCurrentTimeVideo = ((TextView) findViewById(R.id.tvCurrentTimeVideo)); tvTotalTimeVideo = ((TextView) findViewById(R.id.tvTotalTimeVideo)); tvPlayPauseVideo = ((TextView) findViewById(R.id.tvPlayPauseVideo)); tvPause = ((TextView) findViewById(R.id.tvPause)); rlRoot = ((RelativeLayout) findViewById(R.id.rlRoot)); tvSound = ((TextView) findViewById(R.id.tvSound)); //音量 rlControl = ((RelativeLayout) findViewById(R.id.rlControl)); //获取音频管理器 manager = (AudioManager) getSystemService(AUDIO_SERVICE); tvPlayPauseVideo.setBackgroundResource(R.mipmap.pause1); } private void getData() { int position = getIntent().getIntExtra("position", -1); if (position != -1) { video = MainActivity.videos.get(position); } filePath = video.getFilePath(); } private void initMedia() { mediaPlayer = new MediaPlayer(); MediaUtil.playVideo(mediaPlayer); MediaMetadataRetriever mmr = new MediaMetadataRetriever(); mmr.setDataSource(filePath); duration = Integer.parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)); mediaPlayer.reset(); // Log.e(TAG, "initMedia: " + surfaceView.getHolder()); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { try { mediaPlayer.setDataSource(PlayActivity.this, Uri.parse(filePath)); // mediaPlayer.setDataSource(PlayActivity.this, Uri.fromFile(new File(movie.getMovieUrl()))); mediaPlayer.prepareAsync(); //异步 } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { mediaPlayer.stop(); //暂停 mediaPlayer.release(); //注销 mediaPlayer = null; } }); } private void playVideo() { //mediaPlayer准备好后的监听 mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mediaPlayer.start(); setMovieTime(); mediaPlayer.setDisplay(surfaceHolder); //将画面输出到surface上面 updateView(); } }); //mediaPlayer完成后的监听 mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mediaPlayer.stop(); mediaPlayer.reset(); } }); seekbarVideo.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {} @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) { int progress = seekbarVideo.getProgress(); mediaPlayer.seekTo((int) (duration * (progress / 100f))); } }); } private void updateView() { handler.postDelayed(new Runnable() { @Override public void run() { if (mediaPlayer != null && mediaPlayer.isPlaying() && !activityStopped) { int currentPosition = mediaPlayer.getCurrentPosition(); int progress = (int) (currentPosition * 100 / (float) duration); tvCurrentTimeVideo.setText(TimeChangeUtil.milliChangeDate(((long) currentPosition))); seekbarVideo.setProgress(progress); } updateView(); } }, 1000); } private void setMovieTime() { String time = TimeChangeUtil.milliChangeDate(duration); int min = 10; int second = 10; tvTotalTimeVideo.setText(time); tvCurrentTimeVideo.setText(TimeChangeUtil.milliChangeDate(((long) mediaPlayer.getCurrentPosition()))); } /** * 快进快退操作 * @param b */ private void setSpeedReverse(boolean b) { if (b) { currentPosition = mediaPlayer.getCurrentPosition(); mediaPlayer.seekTo(currentPosition + 5000); } else { currentPosition = mediaPlayer.getCurrentPosition(); mediaPlayer.seekTo(currentPosition - 5000); } } private void setPlayOrPause() { if (mediaPlayer.isPlaying()) { tvPlayPauseVideo.setBackgroundResource(R.mipmap.pause1); tvPause.setVisibility(View.GONE); } else { tvPlayPauseVideo.setBackgroundResource(R.mipmap.play1); tvPause.setVisibility(View.VISIBLE); } updateView(); } private void setVolume(boolean b) { //获取当前音量 currentVolume = manager.getStreamVolume(AudioManager.STREAM_MUSIC); if (b) { currentVolume++; } else { currentVolume--; } manager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, AudioManager.FLAG_SHOW_UI); tvSound.setVisibility(View.VISIBLE); tvSound.setText("音量:" + currentVolume); handler.postDelayed(new Runnable() { @Override public void run() { tvSound.setVisibility(View.GONE); } }, 1000); } }
4.Util
public class MediaUtil { private static final String TAG = "test"; public static boolean isPlaying = false; public static MediaPlayer mediaPlayer; public static void playVideo(MediaPlayer media) { mediaPlayer = media; isPlaying = true; } public static void playOrPause(Context context) { if (mediaPlayer != null) { if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); isPlaying = false; } else { mediaPlayer.start(); isPlaying = true; } } } public static List<LocalVideo> getLocalVideo(Context context, String dirPath) { ArrayList<LocalVideo> videos = new ArrayList<>(); String[] projection = { MediaStore.Video.VideoColumns.DATA, MediaStore.Video.Media.TITLE }; Cursor cursor = context.getContentResolver().query( MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, null, null, MediaStore.Video.Media.DEFAULT_SORT_ORDER ); while (cursor.moveToNext()) { String title = cursor.getString((cursor.getColumnIndex(MediaStore.Video.Media.TITLE))); // 标题 String filePath = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA)); // 文件路径 LocalVideo video = new LocalVideo(title, filePath); videos.add(video); } return videos; } public static String getVideoLength(String filePath){ String str = "-1"; long length = new File(filePath).length(); double len = (double) length; if (length == 0) return str; else if (length < 1024) str = (double) (Math.round(len * 10) / 10.0) + "B"; else if (length < 1024*1024) str = (double) (Math.round(len/1024 * 10) / 10.0) + "KB"; else if (length < 1024*1024*1024) str = (double) (Math.round(len / 1024/1024 * 10) / 10.0)+ "MB"; else if (length < 1024*1024*1024*1024) str = (double) (Math.round(len/1024/1024/1024 * 10) / 10.0) + "GB"; return str; } } public class TimeChangeUtil { public static String milliChangeDate(long milli){ return new SimpleDateFormat("mm:ss").format(new Date(milli)); } }
5.适配器
public class MyVideoAdapter extends BaseAdapter { private Context context; private List<LocalVideo> videos; private LayoutInflater inflater; public MyVideoAdapter(Context context, List<LocalVideo> videos) { inflater = LayoutInflater.from(context); this.context = context; this.videos = videos; } public void setVideos(List<LocalVideo> videos) { this.videos = videos; notifyDataSetChanged(); } @Override public int getCount() { return videos.size(); } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(final int position, View convertView, ViewGroup parent) { Holder holder; if (convertView == null) { convertView = inflater.inflate(R.layout.video_item, parent, false); holder = new Holder(convertView); convertView.setTag(holder); } else { holder = ((Holder) convertView.getTag()); } LocalVideo video = videos.get(position); String title = video.getTitle(); String size = MediaUtil.getVideoLength(video.getFilePath()); holder.tvTitle.setText(title); holder.tvSize.setText(size); holder.rlItem.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (callback != null) { callback.playVideo(position); } } }); return convertView; } static class Holder { TextView tvTitle; TextView tvSize; RelativeLayout rlItem; Holder(View view) { tvTitle = (TextView) view.findViewById(R.id.tvTitle); tvSize = (TextView) view.findViewById(R.id.tvSize); rlItem = (RelativeLayout) view.findViewById(R.id.rlItem); } } private PlayCallback callback; public void setCallback(PlayCallback callback) { this.callback = callback; } public interface PlayCallback { void playVideo(int positon); } }
6.布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/rlRoot"> <SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:id="@+id/tvBack" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_width="40dp" android:layout_height="25dp" android:background="@mipmap/arrow_lift" /> <TextView android:id="@+id/tvSound" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="#33ffffff" android:padding="8dp" android:text="音量" android:visibility="gone" /> <TextView android:id="@+id/tvPause" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerInParent="true" android:background="@mipmap/play" android:padding="8dp" android:visibility="gone" /> <RelativeLayout android:id="@+id/rlControl" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="53dp" android:layout_marginBottom="5dp" android:paddingLeft="2dp" android:paddingRight="2dp" > <TextView android:id="@+id/tvPlayPauseVideo" android:layout_marginLeft="20dp" android:layout_width="20dp" android:layout_height="20dp" android:background="@mipmap/play1" /> <TextView android:id="@+id/tvCurrentTimeVideo" android:layout_toRightOf="@+id/tvPlayPauseVideo" android:layout_marginLeft="15dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="00:00" style="@style/VideoTimeStyle" /> <TextView android:id="@+id/tvBias" android:layout_toRightOf="@+id/tvCurrentTimeVideo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="/" style="@style/VideoTimeStyle" /> <TextView android:id="@+id/tvTotalTimeVideo" android:layout_toRightOf="@+id/tvBias" android:layout_marginLeft="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="00:00" style="@style/VideoTimeStyle" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/tvTotalTimeVideo" android:layout_marginBottom="5dp" > <SeekBar android:id="@+id/seekbarVideo" android:layout_marginTop="8dp" style="@style/MySeekBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="0dp" android:layout_marginRight="0dp" android:layout_weight="1" android:progress="0" /> </LinearLayout> </RelativeLayout> </RelativeLayout> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <corners android:radius="5dip" /> <solid android:color="@color/whiteTransparentIII"/> </shape> </item> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <corners android:radius="5dip" /> <solid android:color="@color/orange"/> </shape> </clip> </item> <item android:id="@android:id/progress"> <clip> <shape> <corners android:radius="5dip" /> <solid android:color="@color/orange"/> </shape> </clip> </item> </layer-list>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:state_window_focused="true" android:drawable="@mipmap/player_thumb" /> <item android:state_focused="true" android:state_window_focused="true" android:drawable="@mipmap/player_thumb" /> <item android:state_selected="true" android:state_window_focused="true" android:drawable="@mipmap/player_thumb" /> <item android:drawable="@mipmap/player_thumb" /> </selector>