当前位置: 首页 > news >正文

MediaPlayer视频播放

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/widget34"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >
    <EditText
        android:id="@+id/et_src"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="请输入资源路径……"
        android:textSize="18sp" />

    <SeekBar
        android:id="@+id/seekBar_progress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:id="@+id/widget35"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/btn_play"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="播放" />

        <Button
            android:id="@+id/btn_pause"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="暂停" />

        <Button
            android:id="@+id/btn_replay"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="01"
            android:text="重播" />

        <Button
            android:id="@+id/btn_stop"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="停止" />
    </LinearLayout>

    <SurfaceView
        android:id="@+id/sfView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

   

</LinearLayout>

package com.pas.video.play;

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;

import com.pas.video.play.R;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {
    private EditText et_mediaSrc;
    private Button bt_play, bt_pause, bt_replay, bt_stop;
    private SurfaceView sv;
    private SeekBar seekBar_progress;
    private Timer timer;
    private TimerTask timerTask;
    /**
     * 互斥变量 解决进度条手动改变 与进度条线程中run方法自动改变之间的冲突
     */
    private Boolean ischanging = false;
    // 媒体对象
    private MediaPlayer mediaPlayer;
    private int currentPosition = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	et_mediaSrc = (EditText) findViewById(R.id.et_src);
	sv = (SurfaceView) findViewById(R.id.sfView);
	seekBar_progress = (SeekBar) findViewById(R.id.seekBar_progress);
	seekBar_progress.setOnSeekBarChangeListener(new MySeekListener());
	// 设置SurfaceView不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送用户界面
	// 低版本必须 4.0之上无需设置
	sv.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

	// 应用最小化后的处理与恢复处理
	sv.getHolder().addCallback(new Callback() {

	    // 最小化后 系统自动销毁surfaceview中的holder对象
	    // 保存进度
	    @Override
	    public void surfaceDestroyed(SurfaceHolder holder) {
		System.out.println("Holder销毁");
		if (mediaPlayer != null && mediaPlayer.isPlaying()) {
		    currentPosition = mediaPlayer.getCurrentPosition();
		    stop();
		}
	    }

	    @Override
	    public void surfaceCreated(SurfaceHolder holder) {
		System.out.println("Holder创建");
		if (currentPosition > 0) {
		    play(currentPosition);
		}
	    }

	    @Override
	    public void surfaceChanged(SurfaceHolder holder, int format,
		    int width, int height) {
		System.out.println("Holder大小改变");
	    }
	});
	bt_play = (Button) findViewById(R.id.btn_play);
	bt_pause = (Button) findViewById(R.id.btn_pause);
	bt_replay = (Button) findViewById(R.id.btn_replay);
	bt_stop = (Button) findViewById(R.id.btn_stop);
	bt_play.setOnClickListener(this);
	bt_pause.setOnClickListener(this);
	bt_replay.setOnClickListener(this);
	bt_stop.setOnClickListener(this);

	et_mediaSrc.setText(Environment.getExternalStorageDirectory()
		+ "/2.mp4");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
	// Inflate the menu; this adds items to the action bar if it is present.
	getMenuInflater().inflate(R.menu.main, menu);
	return true;
    }

    private void showToast(String info) {
	Toast.makeText(this, info, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(View v) {
	switch (v.getId()) {
	case R.id.btn_play:
	    play(0);
	    break;
	case R.id.btn_pause:
	    pause();
	    break;
	case R.id.btn_replay:
	    rePlay();
	    break;
	case R.id.btn_stop:
	    stop();
	    break;
	default:
	    break;
	}
    }

    /**
     * 开启进度条
     */
    private void seekBarChanging() {
	seekBar_progress.setMax(mediaPlayer.getDuration());
	seekBar_progress.setProgress(currentPosition);
	timer = new Timer();
	timerTask = new TimerTask() {

	    @Override
	    public void run() {
		if (ischanging == true) {
		    return;
		}
		seekBar_progress.setProgress(mediaPlayer.getCurrentPosition());
	    }
	};
	timer.schedule(timerTask, 0, 10);
    }

    /**
     * 初始化进度条
     */
    private void initSeekBar() {
	timer.cancel();
	seekBar_progress.setProgress(0);
    }

    /**
     * 播放 正常应写在服务中
     * 
     * @param currentPosition2
     */
    private void play(final int Position) {
	String path = et_mediaSrc.getText().toString().trim();
	File file = new File(path);
	if (file.exists()) {
	    if (mediaPlayer != null) {
		mediaPlayer.stop();
		// 释放资源
		mediaPlayer.release();
		mediaPlayer = null;
	    }
	    mediaPlayer = new MediaPlayer();
	    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
	    try {
		// 指定video播放容器
		// 播放视频只多一行
		mediaPlayer.setDisplay(sv.getHolder());

		mediaPlayer.setDataSource(path);
		// 异步的准备 不阻塞主线程 但需要注册准备完毕的回调函数
		mediaPlayer.prepareAsync();
		// 回调
		mediaPlayer.setOnPreparedListener(new OnPreparedListener() {

		    @Override
		    public void onPrepared(MediaPlayer mp) {

			// 进度条
			mediaPlayer.start();
			mediaPlayer.seekTo(Position);
			seekBarChanging();
		    }
		});

		// 播放完毕的回调函数
		mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

		    @Override
		    public void onCompletion(MediaPlayer mp) {
			// 播放完毕后设置播放按钮可用
			bt_play.setEnabled(true);
			initSeekBar();
		    }
		});

		// 播放中出现错误(如流损坏)的回调函数
		mediaPlayer.setOnErrorListener(new OnErrorListener() {

		    @Override
		    public boolean onError(MediaPlayer mp, int what, int extra) {
			stop();
			return false;
		    }
		});

		// 播放开始后设置播放按钮不可用
		bt_play.setEnabled(false);
	    } catch (Exception e) {
		showToast("播放失败");
	    }
	} else {
	    showToast("文件不存在");
	}
    }

    /**
     * 停止播放并回收资源
     */
    private void stop() {
	if (mediaPlayer != null) {
	    if (mediaPlayer.isPlaying()) {
		// 转到开头并关闭对象
		mediaPlayer.seekTo(0);
		mediaPlayer.stop();
	    }
	    // 释放进度条线程
	    initSeekBar();
	    // 释放资源
	    mediaPlayer.release();
	    mediaPlayer = null;

	    // 播放完毕后设置播放按钮可用
	    bt_play.setEnabled(true);
	}
    }

    /**
     * 重新播放
     */
    private void rePlay() {

	if (bt_pause.getText().equals("继续")) {
	    bt_pause.setText("暂停");
	}
	if (mediaPlayer != null && mediaPlayer.isPlaying()) {
	    mediaPlayer.seekTo(0);
	} else {
	    stop();
	    play(0);
	}
    }

    /**
     * 暂停播放
     */
    private void pause() {
	if (mediaPlayer != null && mediaPlayer.isPlaying()) {
	    mediaPlayer.pause();
	    bt_pause.setText("继续");
	} else if (bt_pause.getText().equals("继续")) {
	    mediaPlayer.start();
	    bt_pause.setText("暂停");
	} else {
	    showToast("当前未播放");
	}
    }

    /**
     * 进度条手动处理
     */
    private class MySeekListener implements OnSeekBarChangeListener {

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress,
		boolean fromUser) {
	    if (mediaPlayer == null) {
		return;
	    }
	    if (fromUser) {
		// 如果用户拖动才执行 否则造成进度条线程 多重调用
		ischanging = true;
		mediaPlayer.seekTo(progress);
	    }
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
	    ischanging = true;
	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
	    if (mediaPlayer == null) {
		return;
	    }
	    mediaPlayer.seekTo(seekBar.getProgress());
	    ischanging = false;
	}

    }
}






转载于:https://my.oschina.net/u/1246663/blog/200535

相关文章:

  • Android文本框实现搜索和清空效果
  • strongweak
  • powershell最常用的命令之(一)
  • 左固定右边自适应框架
  • logrotate工具的使用
  • ping,
  • php操作mysql数据库类代码
  • 恶补英语-1
  • 随机选择实现
  • 重读金典------高质量C编程指南(林锐)-------第六章 函数设计
  • Oracle 修改表列属性
  • CKEditor如何统计文字数量
  • Oracle 11G创建表空间、用户、授权命令(Oracle 11g使用)
  • TIMESTAMP with ****问题连不上mysql
  • window.location.href的一种用法
  • Android 控件背景颜色处理
  • FineReport中如何实现自动滚屏效果
  • JS学习笔记——闭包
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • node和express搭建代理服务器(源码)
  • 服务器从安装到部署全过程(二)
  • 回顾 Swift 多平台移植进度 #2
  • 利用jquery编写加法运算验证码
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 如何解决微信端直接跳WAP端
  • 深度学习中的信息论知识详解
  • 我这样减少了26.5M Java内存!
  • 小而合理的前端理论:rscss和rsjs
  • 一个项目push到多个远程Git仓库
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 找一份好的前端工作,起点很重要
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • #git 撤消对文件的更改
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (10)ATF MMU转换表
  • (八)c52学习之旅-中断实验
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (转载)Google Chrome调试JS
  • (转载)深入super,看Python如何解决钻石继承难题
  • .dwp和.webpart的区别
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .net 调用php,php 调用.net com组件 --
  • .NET 设计一套高性能的弱事件机制
  • .net 使用ajax控件后如何调用前端脚本
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .net6+aspose.words导出word并转pdf
  • .考试倒计时43天!来提分啦!
  • :中兴通讯为何成功
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @31省区市高考时间表来了,祝考试成功
  • @TableId注解详细介绍 mybaits 实体类主键注解
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具