zoukankan      html  css  js  c++  java
  • 基于Android的一个简单多媒体播放器

    其实就是一个简单的视频和音频播放小程序! 先看截图:


    本程序是根据网上一个示例更改的:blog.csdn.net/hellogv/article/details/5975864
    上面链接文档中的程序是无法直接(在Android2.3上)执行的,会提示一个:getVideoHeight failed 错误!
    如果通过注释的方法忽略该错误,将会导致音频和视频的进度条无法实时更新;于是本示例抛弃了原文档中的定时器(mTimerTask)控制方法,改用成多线程进行更新。

    下面来看源代码吧,首先是布局文件main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <SeekBar android:id="@+id/SeekBar01" android:layout_height="wrap_content"
    android:layout_width="fill_parent"></SeekBar>
    <LinearLayout android:id="@+id/LinearLayout02"
    android:layout_width="wrap_content" android:layout_height="wrap_content">
    <Button android:id="@+id/Button01" android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:text="播放音频"></Button>
    <Button android:id="@+id/Button02" android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:text="停止播放"></Button>
    </LinearLayout>
    <SeekBar android:id="@+id/SeekBar02" android:layout_height="wrap_content"
    android:layout_width="fill_parent"></SeekBar>
    <SurfaceView android:id="@+id/SurfaceView01"
    android:layout_width="fill_parent" android:layout_height="360px"></SurfaceView>
    <LinearLayout android:id="@+id/LinearLayout02"
    android:layout_width="wrap_content" android:layout_height="wrap_content">
    <Button android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:id="@+id/Button03"
    android:text="播放视频"></Button>
    <Button android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:text="停止播放" android:id="@+id/Button04"></Button>
    </LinearLayout>
    </LinearLayout>

    主要就是使用了线性布局(LinearLayout)的嵌套,其它也没什么特别的。

    然后是AndroidManifest.xml文件,需要添加一个强制竖屏的设置,因为要是允许了重力感应,多媒体的进度条将会变得无法控制。只需在<activity>标签中添加:

                      android:launchMode="singleTask" 
    android:screenOrientation="portrait"

    因为强制设置了竖屏显示,所以布局中<SurfaceView>的高度定义可以根据自己的视频实际尺寸计算一下,免得比例失真!

    关于横屏、竖屏、全屏的设置可以参看:hi.baidu.com/wither/blog/item/7f35f1f2a8828d0ab17ec546.html

    最后就是主程序文件Mplayer.java了:

    package com.ucrobotics.mplayer;
     
    import java.io.IOException;
    import android.app.Activity;
    import android.media.AudioManager;
    import android.media.MediaPlayer;
    import android.net.Uri;
    import android.os.Bundle;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.widget.Button;
    import android.widget.SeekBar;
    import android.widget.Toast;
     
     
    public class Mplayer extends Activity {
    /** Called when the activity is first created. */
     
    private SeekBar skb_audio=null;
    private Button btn_start_audio = null;
    private Button btn_stop_audio = null;
     
    private SeekBar skb_video=null;
    private Button btn_start_video = null;
    private Button btn_stop_video = null;
     
    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
     
    private MediaPlayer m = null;
     
    private String mp3Path = "/sdcard/Music/Young_For_You.mp3";
    private String mp4Path = "/sdcard/Video/mv.mp4";
    private boolean isVideo=false;
    private boolean isAudio=false;
     
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
     
    setContentView(R.layout.main);
     
    //----------Media控件设置---------//
    m=new MediaPlayer();
     
    //播放结束后释放MediaPlayer
    m.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
    public void onCompletion(MediaPlayer arg0) {
    //Toast.makeText(Mplayer.this, "结束", Toast.LENGTH_LONG).show();
    m.release();
    }
    });
     
    btn_start_audio = (Button) this.findViewById(R.id.Button01);
    btn_stop_audio = (Button) this.findViewById(R.id.Button02);
    btn_start_audio.setOnClickListener(new ClickEvent());
    btn_stop_audio.setOnClickListener(new ClickEvent());
    skb_audio=(SeekBar)this.findViewById(R.id.SeekBar01);
    skb_audio.setOnSeekBarChangeListener(new SeekBarChangeEvent());
     
    btn_start_video = (Button) this.findViewById(R.id.Button03);
    btn_stop_video = (Button) this.findViewById(R.id.Button04);
    btn_start_video.setOnClickListener(new ClickEvent());
    btn_stop_video.setOnClickListener(new ClickEvent());
    skb_video=(SeekBar)this.findViewById(R.id.SeekBar02);
    skb_video.setOnSeekBarChangeListener(new SeekBarChangeEvent());
     
    surfaceView = (SurfaceView) findViewById(R.id.SurfaceView01);
    surfaceHolder = surfaceView.getHolder();
    //surfaceHolder.setFixedSize(100, 100);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
     
    /*
    * 按键事件处理
    */

    class ClickEvent implements View.OnClickListener{
    public void onClick(View v) {
    if(v==btn_start_audio)
    {
    //设置audio或video标记,以便控制各自的进度条变化
    isAudio = true;
    isVideo = false;
     
    //恢复到未初始化的状态
    m.reset();
     
    //有两种方式获取资源文件:从工程的resource目录,或是指定路径;鉴于文件比较大,所以本示例均是从SD卡获取
    //m=MediaPlayer.create(TestPlayer.this, R.raw.big);//读取音频
    m=MediaPlayer.create(Mplayer.this, Uri.parse("file://" + mp3Path));
     
    //设置SeekBar的长度
    skb_audio.setMax(m.getDuration());
     
    //每次播放都将进度条重置为0
    skb_audio.setProgress(0);
     
    try {
    m.prepare(); //准备
    } catch (IllegalStateException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    m.start(); //播放
     
    //启动一个新线程用于更新音频的进度条
    aseekth as = new aseekth();
    as.start();
     
    }
    else if(v==btn_stop_audio)
    {
    try{
    m.stop();
    isAudio = false;
    } catch (Exception e) { }
    }
    else if(v==btn_stop_video)
    {
    try{
    m.stop();
    isVideo = false;
    } catch (Exception e) { }
    }
    else if(v==btn_start_video)
    {
    isVideo = true;
    isAudio = false;
     
    m.reset();
     
    //m=MediaPlayer.create(TestPlayer.this, R.raw.test);//读取视频
    m=MediaPlayer.create(Mplayer.this, Uri.parse("file://" + mp4Path));
     
    //设置SeekBar的长度
    skb_video.setMax(m.getDuration());
    //每次播放都将进度条重置为0
    skb_video.setProgress(0);
     
    m.setAudioStreamType(AudioManager.STREAM_MUSIC);
    m.setDisplay(surfaceHolder);//设置屏幕
     
    try {
    m.prepare();
     
    } catch (IllegalArgumentException e) {
    e.printStackTrace();
    } catch (IllegalStateException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    m.start();
     
    //启动一个新线程用于更新视频的进度条
    vseekth vs = new vseekth();
    vs.start();
    }
    }
    }
     
    /*
    * SeekBar进度改变事件
    */

    class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener{
     
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    }
     
    public void onStartTrackingTouch(SeekBar seekBar) {
    }
     
    public void onStopTrackingTouch(SeekBar seekBar) {
    m.seekTo(seekBar.getProgress());
    }
    }
     
    /*
    * 音频进度条线程处理
    */

    private class aseekth extends Thread {
    public void run() {
    try {
    while(isAudio){
    if(skb_audio.getProgress() < m.getCurrentPosition()){
    skb_audio.setProgress(m.getCurrentPosition());
    sleep(10);
    }
    }
    } catch (Exception e) { }
    }
    }
     
    /*
    * 视频进度条线程处理
    */

    private class vseekth extends Thread {
    public void run() {
    try {
    while(isVideo){
    if(skb_video.getProgress() < m.getDuration()){
    skb_video.setProgress(m.getCurrentPosition());
    sleep(10);
    }
    }
    } catch (Exception e) { }
    }
    }
    }


    里面的注释应该很详细了。

    运行本示例注意事项:
    1. 更改源文件的定义:即mp3Path 和 mp4Path,都指向的是SD卡上的资源
    2. 根据自己设备的分辨率适当调整布局中<SurfaceView>的高度

    关于多媒体播放还个参阅另一篇帖子:vanlee820816.blog.163.com/blog/static/17981351200971993443205/

  • 相关阅读:
    【topcoder SRM 702 DIV 2 250】TestTaking
    【24.67%】【codeforces 551C】 GukiZ hates Boxes
    【TP SRM 703 div2 500】 GCDGraph
    【TP SRM 703 div2 250】AlternatingString
    【35.02%】【codeforces 734A】Vladik and flights
    Android总结篇系列:Android Service
    java之常用正则表达式
    一种软件定义的固态盘融合存储方法
    MongoDB常用语句
    编程界十大顶级IDE
  • 原文地址:https://www.cnblogs.com/wzc0066/p/2948218.html
Copyright © 2011-2022 走看看