android播放网络音频

android播放网络音频,很简单的技术,但是可以学习下

很简单的一个获取网络音频播放器,有进度条,播放,暂停,停止,重新播放,支持缓存,以下是源码,希望可以帮到大家

布局文件很简单,就几个按钮,TextView,和SeekBar。

activity_audio_palyer.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/tips"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:text="文件地址" />

        <EditText
            android:id="@+id/file_name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="http://sc1.111ttt.com/2016/1/02/23/195231349486.mp3" />
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="4.0dip"
            android:orientation="horizontal" >

            <Button
                android:id="@+id/btnPlayUrl"
                android:layout_width="80dip"
                android:layout_height="wrap_content"
                android:text="播放" >
            </Button>

            <Button
                android:id="@+id/btnPause"
                android:layout_width="80dip"
                android:layout_height="wrap_content"
                android:text="暂停" >
            </Button>

            <Button
                android:id="@+id/btnStop"
                android:layout_width="80dip"
                android:layout_height="wrap_content"
                android:text="停止" >
            </Button>

            <Button
                android:id="@+id/btnReplay"
                android:layout_width="80dip"
                android:layout_height="wrap_content"
                android:text="重播" >
            </Button>
        </LinearLayout>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="20dip"
            android:orientation="horizontal" >

            <SeekBar
                android:id="@+id/skbProgress"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1.0"
                android:max="100"
                android:paddingLeft="10dip"
                android:paddingRight="10dip" >
            </SeekBar>
        </LinearLayout>
    </LinearLayout>

</FrameLayout>

Player.java文件

public class Player implements OnBufferingUpdateListener, OnCompletionListener,
        MediaPlayer.OnPreparedListener {
    public MediaPlayer mediaPlayer;
    private SeekBar skbProgress;
    private Timer mTimer = new Timer();
    private String videoUrl;
    private boolean pause;
    private int playPosition;

    public Player(String videoUrl, SeekBar skbProgress) {
        this.skbProgress = skbProgress;
        this.videoUrl = videoUrl;
        try {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setOnBufferingUpdateListener(this);
            mediaPlayer.setOnPreparedListener(this);
        } catch (Exception e) {
            Log.e("mediaPlayer", "error", e);
        }

        mTimer.schedule(mTimerTask, 0, 1000);
    }

    /*******************************************************
     * 通过定时器和Handler来更新进度条
     ******************************************************/
    TimerTask mTimerTask = new TimerTask() {
        @Override
        public void run() {
            if (mediaPlayer == null)
                return;
            if (mediaPlayer.isPlaying() && skbProgress.isPressed() == false) {
                handleProgress.sendEmptyMessage(0);
            }
        }
    };

    Handler handleProgress = new Handler() {
        public void handleMessage(Message msg) {
            int position = mediaPlayer.getCurrentPosition();
            int duration = mediaPlayer.getDuration();
            if (duration > 0) {
                long pos = skbProgress.getMax() * position / duration;
                skbProgress.setProgress((int) pos);
            }
        };
    };

    /**
     * 来电话了
     */
    public void callIsComing() {
        if (mediaPlayer.isPlaying()) {
            playPosition = mediaPlayer.getCurrentPosition();// 获得当前播放位置
            mediaPlayer.stop();
        }
    }

    /**
     * 通话结束
     */
    public void callIsDown() {
        if (playPosition > 0) {
            playNet(playPosition);
            playPosition = 0;
        }
    }

    /**
     * 播放
     */
    public void play() {
        playNet(0);
    }

    /**
     * 重播
     */
    public void replay() {
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.seekTo(0);// 从开始位置开始播放音乐
        } else {
            playNet(0);
        }
    }

    /**
     * 暂停
     */
    public boolean pause() {
        if (mediaPlayer.isPlaying()) {// 如果正在播放
            mediaPlayer.pause();// 暂停
            pause = true;
        } else {
            if (pause) {// 如果处于暂停状态
                mediaPlayer.start();// 继续播放
                pause = false;
            }
        }
        return pause;
    }

    /**
     * 停止
     */
    public void stop() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
    }

    @Override
    /**
     * 通过onPrepared播放
     */
    public void onPrepared(MediaPlayer arg0) {
        arg0.start();
        Log.e("mediaPlayer", "onPrepared");
    }

    @Override
    public void onCompletion(MediaPlayer arg0) {
        Log.e("mediaPlayer", "onCompletion");
    }

    @Override
    public void onBufferingUpdate(MediaPlayer arg0, int bufferingProgress) {
        skbProgress.setSecondaryProgress(bufferingProgress);
        int currentProgress = skbProgress.getMax()
                * mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration();
        Log.e(currentProgress + "% play", bufferingProgress + "% buffer");
    }

    /**
     * 播放音乐
     *
     * @param playPosition
     */
    private void playNet(int playPosition) {
        try {
            mediaPlayer.reset();// 把各项参数恢复到初始状态
            mediaPlayer.setDataSource(videoUrl);
            mediaPlayer.prepare();// 进行缓冲
            mediaPlayer.setOnPreparedListener(new MyPreparedListener(
                    playPosition));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private final class MyPreparedListener implements
            android.media.MediaPlayer.OnPreparedListener {
        private int playPosition;

        public MyPreparedListener(int playPosition) {
            this.playPosition = playPosition;
        }

        @Override
        public void onPrepared(MediaPlayer mp) {
            mediaPlayer.start();// 开始播放
            if (playPosition > 0) {
                mediaPlayer.seekTo(playPosition);
            }
        }
    }
}

MainActivity.java文件

public class MainActivity extends Activity {

    private Button btnPause, btnPlayUrl, btnStop,btnReplay;
    private SeekBar skbProgress;
    private Player player;
    private EditText file_name_text;
    private TextView tipsView;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_audio_palyer);

        this.setTitle("在线音乐播放---ouyangpeng编写");  

        btnPlayUrl = (Button) this.findViewById(R.id.btnPlayUrl);
        btnPlayUrl.setOnClickListener(new ClickEvent());  

        btnPause = (Button) this.findViewById(R.id.btnPause);
        btnPause.setOnClickListener(new ClickEvent());  

        btnStop = (Button) this.findViewById(R.id.btnStop);
        btnStop.setOnClickListener(new ClickEvent());  

        btnReplay = (Button) this.findViewById(R.id.btnReplay);
        btnReplay.setOnClickListener(new ClickEvent());  

        file_name_text=(EditText) this.findViewById(R.id.file_name);
        tipsView=(TextView) this.findViewById(R.id.tips);

        skbProgress = (SeekBar) this.findViewById(R.id.skbProgress);
        skbProgress.setOnSeekBarChangeListener(new SeekBarChangeEvent());  

        String url=file_name_text.getText().toString();
        player = new Player(url,skbProgress);  

        TelephonyManager telephonyManager=(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(new MyPhoneListener(), PhoneStateListener.LISTEN_CALL_STATE);
    }

    /**
     * 只有电话来了之后才暂停音乐的播放
     */
    private final class MyPhoneListener extends android.telephony.PhoneStateListener{
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING://电话来了
                player.callIsComing();
                break;
            case TelephonyManager.CALL_STATE_IDLE: //通话结束
                player.callIsDown();
                break;
            }
        }
    }

    class ClickEvent implements OnClickListener {
        @Override
        public void onClick(View arg0) {
            if (arg0 == btnPause) {
                boolean pause=player.pause();
                if (pause) {
                    btnPause.setText("继续");
                    tipsView.setText("暂停播放...");
                }else{
                    btnPause.setText("暂停");
                    tipsView.setText("继续播放...");
                }
            } else if (arg0 == btnPlayUrl) {
                player.play();
                tipsView.setText("开始播放...");
            } else if (arg0 == btnStop) {
                player.stop();
                tipsView.setText("停止播放...");
            } else if (arg0==btnReplay) {
                player.replay();
                tipsView.setText("重新播放...");
            }
        }
    }  

    class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {
        int progress;
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            // 原本是(progress/seekBar.getMax())*player.mediaPlayer.getDuration()
            this.progress = progress * player.mediaPlayer.getDuration()
                    / seekBar.getMax();
        }  

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {  

        }  

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            // seekTo()的参数是相对与影片时间的数字,而不是与seekBar.getMax()相对的数字
            player.mediaPlayer.seekTo(progress);
        }
    }
}

OK,在项目文件AndroidManifest.xml里面添加权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.netmusic"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 注意:这里要加入一个监听电话的权限 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.netmusic.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

这样做出来的就很原始了,1毛钱特效都没有的那种。

按钮这些可以自己定义背景,有专门的媒体按钮,去http://www.iconfont.cn/上找,很多的。

最主要的是咱们的进度条SeekBar,,原始是不是太丑了?来,我们加个样式吧。

在style文件里面:

 </style>
    <style name="Widget.SeekBar.Normal" parent="@android:style/Widget.SeekBar">
        <item name="android:maxHeight">8.0dip</item>
        <item name="android:indeterminateOnly">false</item>
        <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
        <item name="android:progressDrawable">@drawable/seekbar_horizontal</item>
        <item name="android:minHeight">8.0dip</item>
        <item name="android:thumb">@drawable/seek_thumb</item>
        <item name="android:thumbOffset">10.0dip</item>
    </style> 

新建seekbar_horizontal.xml,drawable里面的

<?xml version="1.0" encoding="UTF-8"?>
<layer-list
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background" android:drawable="@drawable/seek_bkg" />
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="2.0dip" />
                <gradient android:startColor="#80ffd300" android:endColor="#a0ffcb00" android:angle="270.0" android:centerY="0.75" android:centerColor="#80ffb600" />
            </shape>
        </clip>
    </item>
    <item android:id="@android:id/progress">
        <clip android:drawable="@drawable/seek" />
    </item>
</layer-list> 

ok,还有几个图片素材

seek.9.png

seek_bkg.9.png

seek_thumb.png

代码里面引用:

            <SeekBar
                android:id="@+id/skbProgress"
                style="@style/Widget.SeekBar.Normal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1.0"
                android:max="100"
                android:paddingLeft="10dip"
                android:paddingRight="10dip" >
            </SeekBar>

这样就可以了,看下效果:

比原来的是不是好看很多?

希望可以帮到大家

有什么问题可以加我QQ问我:1453022932

时间: 2024-10-25 19:55:53

android播放网络音频的相关文章

vitamio播放网络音频的折腾

下载了最新的vitamio sdk和sample,结果,只有videoview subtitle那个activity的示例,可以使用,其他的都不能正常播放. 但用videoview来播放音频,总不是办法.比如锁屏或是切换到其他应用时,播放就会停止.这本来是正常的(对于播放视频来讲),但对于播放音频来讲,就不合适了. 加了vitamio的群,但没有人回复. 后来,再从github上,找稍老的vitamio源码,终于解决了. 原文首发自我的主力博客: http://anforen.com/wp/20

关于iOS网络音频播放的一些详解

在日常的iOS开发中,我们通常会遇到媒体播放的问题,XCode中已经为我们提供了功能非常强大的AVFoundation框架和MediaPlayer框架.其中AVFoundation框架中的AVAudioPlayer主要用于播放本地音频,也可以播放网络音频,但是需要先将网络数据转化为data数据,用户体验较差,所有苹果公司提供了功能强大的AVPlayer用于播放网络音频(既流媒体),效果和可控性都比较好,现在就重点介绍下AVPlayer中网络音频的播放: 下边是一个简单的实例: OK,一个简单地音

ios开发——实用技术篇&amp;网络音频播放

网络音频播放 在日常的iOS开发中,我们通常会遇到媒体播放的问题,XCode中已经为我们提供了功能非常强大的AVFoundation框架和 MediaPlayer框架.其中AVFoundation框架中的AVAudioPlayer主要用于播放本地音频,也可以播放网络音频,但是需要先将 网络数据转化为data数据,用户体验较差,所有苹果公司提供了功能强大的AVPlayer用于播放网络音频(既流媒体),效果和可控性都比较好,现在就 重点介绍下AVPlayer中网络音频的播放: 下边是一个简单的实例:

音频对列服务——播放网络的音频——转载

无论是前面的录音还是音频播放均不支持网络流媒体播放,当然对于录音来说这种需求可能不大,但是对于音频播放来说有时候就很有必要了. AVAudioPlayer只能播放本地文件,并且是一次性加载所以音频数据,初始化AVAudioPlayer时指定的URL也只能是File URL而不能是HTTP URL.当然,将音频文件下载到本地然后再调用AVAudioPlayer来播放也是一种播放网络音频的办法,但是这种方式最大的弊端就是必须等到整个音 频播放完成才能播放,而不能使用流式播放,这往往在实际开发中是不切

如何在Android中播放网络传输过来的AAC音频?

============问题描述============ 如何在Android中播放网络传输过来的AAC音频?每个包都有ADTS头的. ============解决方案1============ 如果是应用的话,直接设置MediaPlayer setDataSource设置为网络音频的uri,然后prepareAsync(), prepare完成后调用start不就可以了吗? framework层的话还是要用aacdecoder进行解码播放,要么用软件解码,要么用硬件解码.

Android中的音频播放(MediaPlayer和SoundPool)

Android中音频和视频的播放我们最先想到的就是MediaPlayer类了,该类提供了播放.暂停.停止.和重复播放等方法.该类位于android.media包下,详见API文档.其实除了这个类还有一个音乐播放类那就是SoundPool,这两个类各有不同分析一下便于大家理解 MediaPlayer: 此类适合播放较大文件,此类文件应该存储在SD卡上,而不是在资源文件里,还有此类每次只能播放一个音频文件. 此类用法如下: 1.从资源文件中播放 MediaPlayer   player  =   n

【转】Android播放音频MediaPlayer的几种方式介绍

接下来笔者介绍一下Android中播放音频的几种方式,android.media包下面包含了Android开发中媒体类,当然笔者不会依次去介绍,下面介绍几个音频播放中常用的类: 1.使用MediaPlayer播放音频 MediaPlayer的功能很强大,下面附上一张该类封装音频的生命周期图: MediaPlayer支持AAC.AMR.FLAC.MP3.MIDI.OGG.PCM等格式,MediaPlayer可以通过设置元数据和播放源来音频. 1.1播放Raw文件夹下面音频的元数据 //直接创建,不

Android Multimedia框架总结(二)MediaPlayer框架及播放网络视频案例

前言:前面一篇我们介绍MediaPlayer相关方法,有人说,没有实际例子,看得不是很明白,今天在分析MediaPlayer时,顺带一个播放网络视频例子.可以自行试试.今天分析的都是下几篇介绍各个模块进行铺垫. Android中的MediaPlayer框架 MediaPlayer播放视频主要模块 播放主要模块对应组件 MediaPlayer方法对应有效状态及无效状态 案例:Mediaplayer播放网络视频 Android中的MediaPlayer框架 MediaPlayer播放视频主要模块 播

照相、从相册上取照片、播放音频、播放本地视频、播放网络视频、MPMoviePlayerController

一.照相.从相册上去照片 1. 先判断是否支持照相功能 *判断当前设备是否支持照相功能,支持返回YES 否则返回NO 注意:模拟器不支持照相功能 把握一个原则只要是物理硬件相关的功能模拟器都不支持 例如: UIImagePickerController 专门处理与照片相关的功能类 是一个控制器 继承于导航视图控制器 if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]