音乐在线播放Demo
本事例的界面很简单,一个按钮用来开始缓冲音乐,一个进度条用来显示音乐的缓冲进度和播放进度,后面是一个文本用来显示音乐的播放时间,还有一个图片按钮用来播放和暂停音乐。
在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" android:padding="10px"android:background="@drawable/back"><TextView android:id="@+id/text_kb_streamed"android:layout_width="fill_parent" android:layout_height="wrap_content"android:textStyle="bold" android:text="流媒体测试" /><Button android:id="@+id/button_stream" android:layout_width="wrap_content"android:layout_height="wrap_content" android:layout_marginTop="10px"style="?android:attr/buttonStyleSmall" android:text="开始缓冲" /><RelativeLayout android:layout_width="wrap_content"android:layout_height="wrap_content"><SeekBar android:id="@+id/progress_bar" android:layout_height="wrap_content"android:layout_width="200px" style="?android:attr/progressBarStyleHorizontal" /><TextView android:id="@+id/playTime" android:layout_width="wrap_content"android:layout_height="wrap_content" android:layout_toRightOf="@id/progress_bar"android:text="00:00"></TextView></RelativeLayout><RelativeLayout android:layout_width="wrap_content"android:layout_height="wrap_content"><ImageButton android:id="@+id/button_play"android:layout_width="wrap_content" android:layout_height="wrap_content"android:layout_marginTop="5px" style="?android:attr/buttonStyleSmall"android:src="@drawable/button_pause" /></RelativeLayout> </LinearLayout>
流媒体类
新建流媒体类StreamingMediaPlayer。
1. 构造函数StreamingMediaPlayerStreamingMediaPlayer(Context context, ImageButton playButton, Button streamButton, SeekBar progressBar,TextView playTime)传递context(上下文)和主界面UI元素,以便在程序中更新界面。代码如下;
public StreamingMediaPlayer(Context context, ImageButton playButton, Button streamButton, SeekBar progressBar,TextView playTime) {this.context = context;this.playButton = playButton;this.playTime=playTime; //播放的进度时刻this.progressBar = progressBar;}
2. startStreaming(final String mediaUrl, long mediaLengthInKb, long mediaLengthInSeconds)方法,传递音频的URL以及在更新进度条中使用的两个元素。在startStreaming()中开启一个线程,然后调用downloadAudioIncrement()方法。
public void startStreaming(final String mediaUrl, long mediaLengthInKb, long mediaLengthInSeconds) throws IOException {this.mediaLengthInKb = mediaLengthInKb;this.mediaLengthInSeconds = mediaLengthInSeconds;Runnable r = new Runnable() { public void run() { try { downloadAudioIncrement(mediaUrl);} catch (IOException e) {Log.e(getClass().getName(), "Unable to initialize the MediaPlayer for fileUrl=" + mediaUrl, e);return;} } }; new Thread(r).start();}
3. downloadAudioIncrement(String mediaUrl)方法通过传递的URL地址下载音频文件,因为多媒体播放器锁定它所播放的文件,所以我们不能简单的追加内容,然后通过testMediaBuffer()方法测试,如果是第一次播放,则判断缓冲的内容是否达到足够的内容,达到的话就调用startMediaPlayer()方法进行播放,如果不是第一次播放的话,并且多媒体已播放的进度和多媒体的总进度的差小于一秒,调用transferBufferToMediaPlayer()方法。代码如下;
public void downloadAudioIncrement(String mediaUrl) throws IOException {URLConnection cn = new URL(mediaUrl).openConnection(); cn.connect(); InputStream stream = cn.getInputStream();if (stream == null) {Log.e(getClass().getName(), "Unable to create InputStream for mediaUrl:" + mediaUrl);}downloadingMediaFile = new File(context.getCacheDir(),"downloadingMedia.dat");if (downloadingMediaFile.exists()) {downloadingMediaFile.delete(); //如果下载完成则删除 }FileOutputStream out = new FileOutputStream(downloadingMediaFile); byte buf[] = new byte[16384];int totalBytesRead = 0, incrementalBytesRead = 0;do {int numread = stream.read(buf); if (numread <= 0) break; out.write(buf, 0, numread);totalBytesRead += numread;incrementalBytesRead += numread;totalKbRead = totalBytesRead/1000;//totalKbRead表示已经下载的文件大小 testMediaBuffer(); fireDataLoadUpdate();} while (validateNotInterrupted()); stream.close();if (validateNotInterrupted()) {fireDataFullyLoaded();}} private boolean validateNotInterrupted() {if (isInterrupted) {if (mediaPlayer != null) {mediaPlayer.pause();}return false;} else {return true;}}private void testMediaBuffer() {Runnable updater = new Runnable() {public void run() {if (mediaPlayer == null) {if ( totalKbRead >= INTIAL_KB_BUFFER) {try {startMediaPlayer();} catch (Exception e) {Log.e(getClass().getName(), "Error copying buffered conent.", e); }}} else if ( mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000 ){ transferBufferToMediaPlayer();}}};handler.post(updater);}
4. startMediaPlayer()方法用来播放音频文件,首先调用moveFile()方法将下载的文件复制,用mediaPlayer的API播放文件,startPlayProgressUpdater()方法更新进度条。
private void startMediaPlayer() {try { File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat");moveFile(downloadingMediaFile,bufferedFile);Log.e(getClass().getName(),"Buffered File path: " + bufferedFile.getAbsolutePath());Log.e(getClass().getName(),"Buffered File length: " + bufferedFile.length()+"");mediaPlayer = createMediaPlayer(bufferedFile);mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.start();startPlayProgressUpdater(); playButton.setEnabled(true);} catch (IOException e) {Log.e(getClass().getName(), "Error initializing the MediaPlayer.", e);} }
5. createMediaPlayer()方法用来得到一个MediaPlayer对象。
private MediaPlayer createMediaPlayer(File mediaFile)throws IOException {MediaPlayer mPlayer = new MediaPlayer();mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {public boolean onError(MediaPlayer mp, int what, int extra) {Log.e(getClass().getName(), "Error in MediaPlayer: (" + what +") with extra (" +extra +")" );return false;}});FileInputStream fis = new FileInputStream(mediaFile);mPlayer.setDataSource(fis.getFD());//此方法返回与流相关联的文件说明符。 mPlayer.prepare();return mPlayer;}
6. transferBufferToMediaPlayer()方法将下载的文件复制到一个临时的缓存文件中,暂停音频播放,如果音频正在播放或者多媒体的总长度和多媒体已播放的长度之差小于一秒的时候继续播放。
private void transferBufferToMediaPlayer() {try {boolean wasPlaying = mediaPlayer.isPlaying();int curPosition = mediaPlayer.getCurrentPosition(); File oldBufferedFile = new File(context.getCacheDir(),"playingMedia" + counter + ".dat");File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat"); bufferedFile.deleteOnExit(); moveFile(downloadingMediaFile,bufferedFile);mediaPlayer.pause(); mediaPlayer = createMediaPlayer(bufferedFile);mediaPlayer.seekTo(curPosition); boolean atEndOfFile = mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000;if (wasPlaying || atEndOfFile){mediaPlayer.start();} oldBufferedFile.delete(); }catch (Exception e) {Log.e(getClass().getName(), "Error updating to newly loaded content.", e); }}
7. fireDataLoadUpdate()方法开启一个线程根据已下载的文件大小更新进度条。
private void fireDataLoadUpdate() {Runnable updater = new Runnable() {public void run() {float loadProgress = ((float)totalKbRead/(float)mediaLengthInKb);progressBar.setSecondaryProgress((int)(loadProgress*100));}};handler.post(updater);}
8. fireDataFullyLoaded()方法开启一个线程调用transferBufferToMediaPlayer()方法复制缓存文件,之后播放,然后删除下载的临时文件。
private void fireDataFullyLoaded() {Runnable updater = new Runnable() { public void run() {transferBufferToMediaPlayer();downloadingMediaFile.delete();}};handler.post(updater);}
9. startPlayProgressUpdater()方法根据播放的进度更新进度条,并且显示播放的时间进度。
public void startPlayProgressUpdater() {float progress = (((float)mediaPlayer.getCurrentPosition()/1000)/mediaLengthInSeconds);progressBar.setProgress((int)(progress*100));int pos=mediaPlayer.getCurrentPosition();int min = (pos/1000)/60;int sec = (pos/1000)%60;if(sec<10)playTime.setText(""+min+":0"+sec);//把音乐播放的进度,转换成时间elseplayTime.setText(""+min+":"+sec);if (mediaPlayer.isPlaying()) {Runnable notification = new Runnable() {public void run() {startPlayProgressUpdater();}};handler.postDelayed(notification,1000);}}
10. moveFile(File oldLocation, File newLocation)方法用来实现文件的复制。代码如下;
public void moveFile(File oldLocation, File newLocation)throws IOException {if ( oldLocation.exists( )) {BufferedInputStream reader = new BufferedInputStream( new FileInputStream(oldLocation) );BufferedOutputStream writer = new BufferedOutputStream( new FileOutputStream(newLocation, false));try {byte[] buff = new byte[8192];int numChars;while ( (numChars = reader.read( buff, 0, buff.length ) ) != -1) {writer.write( buff, 0, numChars );}} catch( IOException ex ) {throw new IOException("IOException when transferring " + oldLocation.getPath() + " to " + newLocation.getPath());} finally {try {if ( reader != null ){ writer.close();reader.close();}} catch( IOException ex ){Log.e(getClass().getName(),"Error closing files when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() ); }}} else {throw new IOException("Old location does not exist when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() );}}
业务代码
在MediaPlayer中实现流媒体的测试,通过流媒体的构造函数实例化流媒体类,然后调用流媒体的tartStreaming()方法根据传递的URL地址,实现音乐的在线播放。代码如下;
package com.sharpandroid.music.activity;import java.io.IOException;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ImageButton;import android.widget.SeekBar;import android.widget.TextView;import com.sharpandroid.music.R;import com.sharpandroid.music.StreamingMediaPlayer;public class MediaPlayer extends Activity {private Button streamButton;private ImageButton playButton;private boolean isPlaying;private TextView playTime;private StreamingMediaPlayer audioStreamer;@Overridepublic void onCreate(Bundle icicle) {super.onCreate(icicle);setContentView(R.layout.main);initControls();} private void initControls() {playTime=(TextView) findViewById(R.id.playTime);streamButton = (Button) findViewById(R.id.button_stream);streamButton.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {startStreamingAudio();}});playButton = (ImageButton) findViewById(R.id.button_play);playButton.setEnabled(false);playButton.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {if (audioStreamer.getMediaPlayer().isPlaying()) {audioStreamer.getMediaPlayer().pause();playButton.setImageResource(R.drawable.button_play);} else {audioStreamer.getMediaPlayer().start();audioStreamer.startPlayProgressUpdater();playButton.setImageResource(R.drawable.button_pause);}isPlaying = !isPlaying;}});}private void startStreamingAudio() {try { final SeekBar progressBar = (SeekBar) findViewById(R.id.progress_bar);if ( audioStreamer != null) {audioStreamer.interrupt();}audioStreamer = new StreamingMediaPlayer(this, playButton, streamButton, progressBar,playTime);audioStreamer.startStreaming("http://www.ktcm.net/music/00.mp3",5208, 216);streamButton.setEnabled(false);} catch (IOException e) {Log.e(getClass().getName(), "Error starting to stream audio.", e); }}}
详细的源码下载地址
转载于:https://www.cnblogs.com/vus520/archive/2012/05/14/2561984.html
音乐在线播放Demo相关推荐
- 独家首发DJ舞曲音乐在线播放微信小程序源码下载支持多分类歌曲
这是一款音乐播放小程序源码 音乐内容是属于DJ,电音,舞曲等等这类型的 该小程序的歌曲有七大分类,分别是: 第一分类热门推荐 第二分类中文舞曲 第三分类英文舞曲 第四分类慢摇舞曲 第五分类舞曲串烧 第 ...
- 简单的音乐在线播放网页
调用网易云提供的音乐接口,编写一个简易的音乐在线播放网页 一.功能实现: 1.通过在输入框输入要查询的文字,调用后台接口获取响应的数据,并把需要的数据渲染到左侧. 2.通过点击可以选中左侧播放栏的某一 ...
- Java和vue实现音乐播放器_vue实现的网易云音乐在线播放和下载功能案例
本文实例讲述了vue实现的网易云音乐在线播放和下载功能.分享给大家供大家参考,具体如下: 效果如图: 完整代码: Document html, body { height: 100%; padding ...
- 小项目----音乐在线播放器
目录 音乐播放器 项目功能: 项目框架: 项目的创建很重要: 数据库设计 在idea中配置数据库和xml 一.登录板块设计 1创建User类 2创建UserMapper和Controller接口 3. ...
- 如何使用java实现一个音乐在线播放系统web智能音乐推荐平台使用ssm+springboot架构
环境需要 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的.其他版本理论上也可以. 2.IDE环境:IDEA,Eclipse,Myeclipse都可以.推荐IDEA; 3.tomc ...
- android 随机播放代码,Android | 一个随机播放网络音乐的小 Demo
前言 是这样,前几天接触到一个可以随机获取网络音乐及其热评的 API(关于该API:github.com/isecret/yun- ),于是乎就想着要做一个小 demo 来练练手吧! 目前的效果就是上 ...
- html在线音频播放器实训总结,HTML5音乐列表播放器SMusic开发总结
前段时间写过一篇介绍简单音乐播放器效果开发的博文<为你的博客添加简单的CSS3音乐播放器>,实现了单曲循环播放效果,这个效果也是我的博客首页一直有的效果,同时文中也介绍了一些简单的HTML ...
- 计算机毕设网页设计源码——HTML+CSS+JS+Bootstrap在线音乐试听播放网站模板
HTML5期末大作业:HTML+CSS+JS+Bootstrap在线音乐试听播放网站模板(24页) 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码 常见网页设计作业题材 ...
- 网页中怎样在线播放音乐和视频
代码一: <object classid=clsid:22d6f312-b0f6-11d0-94ab-0080c74c7e95 width=350 height=70><param ...
最新文章
- python股票自动交易从零开始-python程序化交易编程-python制作自动交易程序!
- 基于shiro的改造集成真正支持restful请求
- 1120 Friend Numbers
- 算法:回溯五 数组全排列permutations
- 高手详解SQL性能优化十条经验
- 计算机算法设计与分析 第4版 (王晓东) 重点题
- 阿里电话面试面试题总结,附答案!
- CKEditor5安装LaTeX数学公式插件
- pandas数据分组与聚合
- 创世神曲java官网_创世神曲官网下载
- 量化交易8-backtrader回测道氏理论中反转形态K线形态图
- Chrome谷歌浏览器连接路由器不上
- 51nod 1535 深海探险【思维+并查集】
- Python小黄人绘制
- css3 缩放scale()方法
- 安师大计算机系导师,安徽师范大学数学计算机科学学院导师介绍:陈付龙
- 如何制作GIF表情包,动态GIF怎么做
- 光纤布线兵法之特色产品(一)
- TensorFlow Lite 开发手册(5)——TensorFlow Lite模型使用实例(分类模型)
- 第一周,人工智能学习总结