- 浏览: 157898 次
- 性别:
- 来自: 海口
文章分类
最新评论
-
alienxy:
望楼主能提供源码参考,感激不尽。1291365391@qq.c ...
对myflow WEB版工作流设计器进行改进-增加删除功能 -
oushaomeng2011:
楼主能否发一份源码呢,现在项目需要参考类似流程图设计,希望能提 ...
对myflow WEB版工作流设计器进行改进-增加删除功能 -
tuohuang0303:
楼主能否发一份源码呢,现在项目需要参考类似流程图设计,希望能提 ...
对myflow WEB版工作流设计器进行改进-增加删除功能 -
欧阳陈曦:
楼主能不能提供下代码万分感谢。753095374@qq.com ...
对myflow WEB版工作流设计器进行改进-增加删除功能 -
huan890308:
亲 能不能把源码发一份啊 拜谢拜谢!402197729@qq ...
对myflow WEB版工作流设计器进行改进-增加删除功能
package com.shadow.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import com.shadow.service.AudioPlayService.LocalBinder; import android.app.Service; import android.content.Context; import android.content.Intent; import android.media.MediaPlayer; import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.util.Log; import android.widget.Button; import android.widget.ImageButton; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; /** * MediaPlayer does not yet support streaming from external URLs so this class provides a pseudo-streaming function * by downloading the content incrementally & playing as soon as we get enough audio in our temporary storage. */ public class StreamingMediaPlayer extends Service{ private static final int INTIAL_KB_BUFFER = 96*10/8;//assume 96kbps*10secs/8bits per byte private TextView textStreamed; private ImageButton playButton; private ProgressBar progressBar; // Track for display by progressBar private long mediaLengthInKb, mediaLengthInSeconds; private int totalKbRead = 0; // Create Handler to call View updates on the main UI thread. private final Handler handler = new Handler(); private MediaPlayer mediaPlayer; private File downloadingMediaFile; private boolean isInterrupted; private Context context; private int counter = 0; private static Runnable r; private static Thread playerThread; private LocalBinder localBinder = new LocalBinder(); private MediaPlayer player; private boolean isPause = false; //播放器是否处于暂停状态 private boolean isSame = false; //所点播歌曲是否是当前播放歌曲 private Integer position = -1; //设置播放标记 private List<String> music_name; //歌曲列表 private List<String> music_path; public StreamingMediaPlayer(Context context,TextView textStreamed, ImageButton playButton, Button streamButton,ProgressBar progressBar) { this.context = context; this.textStreamed = textStreamed; this.playButton = playButton; this.progressBar = progressBar; } /** * Progressivly download the media to a temporary location and update the MediaPlayer as new content becomes available. */ public void startStreaming(final String mediaUrl, long mediaLengthInKb, long mediaLengthInSeconds) throws IOException { this.mediaLengthInKb = mediaLengthInKb; this.mediaLengthInSeconds = mediaLengthInSeconds; r = new Runnable() { public void run() { try { Log.i("downloadAudioIncrement", "downloadAudioIncrement"); downloadAudioIncrement(mediaUrl); } catch (IOException e) { Log.e(getClass().getName(), "Unable to initialize the MediaPlayer for fileUrl=" + mediaUrl, e); return; } } }; playerThread = new Thread(r); playerThread.start(); //new Thread(r).start(); } /** * Download the url stream to a temporary location and then call the setDataSource * for that local file */ public void downloadAudioIncrement(String mediaUrl) throws IOException { URLConnection cn = new URL(mediaUrl).openConnection(); cn.addRequestProperty("User-Agent","NSPlayer/10.0.0.4072 WMFSDK/10.0"); 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"); // Just in case a prior deletion failed because our code crashed or something, we also delete any previously // downloaded file to ensure we start fresh. If you use this code, always delete // no longer used downloads else you'll quickly fill up your hard disk memory. Of course, you can also // store any previously downloaded file in a separate data cache for instant replay if you wanted as well. 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; testMediaBuffer(); fireDataLoadUpdate(); } while (validateNotInterrupted()); stream.close(); if (validateNotInterrupted()) { fireDataFullyLoaded(); } } private boolean validateNotInterrupted() { if (isInterrupted) { if (mediaPlayer != null) { mediaPlayer.pause(); //mediaPlayer.release(); } return false; } else { return true; } } /** * Test whether we need to transfer buffered data to the MediaPlayer. * Interacting with MediaPlayer on non-main UI thread can causes crashes to so perform this using a Handler. */ private void testMediaBuffer() { Runnable updater = new Runnable() { public void run() { if (mediaPlayer == null) { // Only create the MediaPlayer once we have the minimum buffered data 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 ){ // NOTE: The media player has stopped at the end so transfer any existing buffered data // We test for < 1second of data because the media player can stop when there is still // a few milliseconds of data left to play transferBufferToMediaPlayer(); } } }; handler.post(updater); } private void startMediaPlayer() { try { File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat"); // We double buffer the data to avoid potential read/write errors that could happen if the // download thread attempted to write at the same time the MediaPlayer was trying to read. // For example, we can't guarantee that the MediaPlayer won't open a file for playing and leave it locked while // the media is playing. This would permanently deadlock the file download. To avoid such a deadloack, // we move the currently loaded data to a temporary buffer file that we start playing while the remaining // data downloads. moveFile(downloadingMediaFile,bufferedFile); Log.e(getClass().getName(),"Buffered File path: " + bufferedFile.getAbsolutePath()); Log.e(getClass().getName(),"Buffered File length: " + bufferedFile.length()+""); mediaPlayer = createMediaPlayer(bufferedFile); // We have pre-loaded enough content and started the MediaPlayer so update the buttons & progress meters. mediaPlayer.start(); startPlayProgressUpdater(); playButton.setEnabled(true); } catch (IOException e) { Log.e(getClass().getName(), "Error initializing the MediaPlayer.", e); return; } } public void pausePlayer(){ try { getMediaPlayer().pause(); } catch (Exception e) { e.printStackTrace(); } } public void startPlayer(){ getMediaPlayer().start(); } public void stopPlayer(){ getMediaPlayer().stop(); } /** * 根据文件创建一个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; } }); // It appears that for security/permission reasons, it is better to pass a FileDescriptor rather than a direct path to the File. // Also I have seen errors such as "PVMFErrNotSupported" and "Prepare failed.: status=0x1" if a file path String is passed to // setDataSource(). So unless otherwise noted, we use a FileDescriptor here. FileInputStream fis = new FileInputStream(mediaFile); mPlayer.setDataSource(fis.getFD()); mPlayer.prepare(); return mPlayer; }
/** * 把缓存转化成mediaplay对象 * Transfer buffered data to the MediaPlayer. * NOTE: Interacting with a MediaPlayer on a non-main UI thread can cause thread-lock and crashes so * this method should always be called using a Handler. */ private void transferBufferToMediaPlayer() { try { // First determine if we need to restart the player after transferring data...e.g. perhaps the user pressed pause boolean wasPlaying = mediaPlayer.isPlaying(); int curPosition = mediaPlayer.getCurrentPosition(); // Copy the currently downloaded content to a new buffered File. Store the old File for deleting later. File oldBufferedFile = new File(context.getCacheDir(),"playingMedia" + counter + ".dat"); File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat"); // This may be the last buffered File so ask that it be delete on exit. If it's already deleted, then this won't mean anything. If you want to // keep and track fully downloaded files for later use, write caching code and please send me a copy. bufferedFile.deleteOnExit(); moveFile(downloadingMediaFile,bufferedFile); // Pause the current player now as we are about to create and start a new one. So far (Android v1.5), // this always happens so quickly that the user never realized we've stopped the player and started a new one mediaPlayer.pause(); // Create a new MediaPlayer rather than try to re-prepare the prior one. mediaPlayer = createMediaPlayer(bufferedFile); mediaPlayer.seekTo(curPosition); // Restart if at end of prior buffered content or mediaPlayer was previously playing. // NOTE: We test for < 1second of data because the media player can stop when there is still // a few milliseconds of data left to play boolean atEndOfFile = mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000; if (wasPlaying || atEndOfFile){ mediaPlayer.start(); } // Lastly delete the previously playing buffered File as it's no longer needed. oldBufferedFile.delete(); }catch (Exception e) { Log.e(getClass().getName(), "Error updating to newly loaded content.", e); } } private void fireDataLoadUpdate() { Runnable updater = new Runnable() { public void run() { //textStreamed.setText((totalKbRead + " Kb read")); float loadProgress = ((float)totalKbRead/(float)mediaLengthInKb); //progressBar.setSecondaryProgress((int)(loadProgress*100)); } }; handler.post(updater); } private void fireDataFullyLoaded() { Runnable updater = new Runnable() { public void run() { transferBufferToMediaPlayer(); // Delete the downloaded File as it's now been transferred to the currently playing buffer file. downloadingMediaFile.delete(); //textStreamed.setText(("Audio full loaded: " + totalKbRead + " Kb read")); } }; handler.post(updater); } //TODO 这个方法应该可以控制歌曲的播放 public MediaPlayer getMediaPlayer() { return mediaPlayer; } public void startPlayProgressUpdater() { float progress = (((float)mediaPlayer.getCurrentPosition()/1000)/mediaLengthInSeconds); progressBar.setProgress((int)(progress*100)); if (mediaPlayer.isPlaying()) { Runnable notification = new Runnable() { public void run() { startPlayProgressUpdater(); } }; handler.postDelayed(notification,1000); } } public void interrupt() { playButton.setEnabled(false); isInterrupted = true; validateNotInterrupted(); } /** * Move the file in oldLocation to 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() ); } } /** * 獲取service中的播放器对象 * @return 播放器对象 */ public MediaPlayer getPlayer() { return this.player; } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); /** * 1.现在需要的就是做从PlayActivity里获取歌曲列表,和歌曲路径,歌曲手名 * 并存放到各个集合里 * 2.之后就是对对这些数组进行处理 */ music_name = new ArrayList<String>(); music_path = new ArrayList<String>(); String info = intent.getStringExtra("info"); //songPath = intent.getStringExtra("songPath"); Toast.makeText(getApplicationContext(), "歌曲播放异常", Toast.LENGTH_SHORT).show(); player = new MediaPlayer(); try { playMusic(info); } catch (Exception e) { Toast.makeText(getApplicationContext(), "歌曲播放异常", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } } //播放音乐 private void playMusic(String info) throws Exception { if ("play".equals(info)) { if (isPause) {// 暂停后,继续播放 player.start(); isPause = false; } else if (isSame) {// 如果现在播放和与所点播歌曲时同一首,继续播放所选歌曲 player.start(); } else {// 点播某一首歌曲 play(); } } else if ("pause".equals(info)) { player.pause();// 暂停 isPause = true; } else if ("before".equals(info)) { playBefore();// 播放上一首 } else if ("after".equals(info)) { playAfter();// 播放下一首 } } private void play() throws Exception { //TODO 获取歌曲路径 try { Log.i("playtest", "playtest"); // myApp.setPlaying_position(position); //设置歌曲 当前的播放标记 player.reset(); //player.setDataSource(songPath); player.start(); //musicName = music_name.get(position); } catch (Exception e) { e.printStackTrace(); } } private void playBefore() throws Exception { if (position == 0) { position = music_name.size() - 1; } else { position--; } play(); } private void playAfter() throws Exception { if (position == 0) { position = music_name.size() + 1; } else { position++; } play(); } public class LocalBinder extends Binder { public StreamingMediaPlayer getService() { return StreamingMediaPlayer.this; } } @Override public void onDestroy() { super.onDestroy(); } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public IBinder onBind(Intent intent) { return localBinder; } }
发表评论
-
关注比分在线订阅号
2014-11-11 09:05 196订阅号:wapzq101 二维码 -
最新的产品开发,其实就是在参照
2014-11-07 23:03 1109引导页 四大块 ... -
初识微信订阅号开发
2014-07-30 11:59 1346初识微信订阅号,想实现一个指令模式,方便使用者能直接通过微信 ... -
仿iPhone的日期时间选择器
2013-09-06 16:17 11930仿iPhone的日期时间选择器 可选只选择日期,也可以同 ... -
E人E本专版公文手写批示
2013-08-21 17:21 1515尝试写一个E人E本T7专版OA公文手写批示APP。 ... -
发现与探索apk开发
2012-06-21 15:25 1306善于发现与探索互联网上有趣的信息,以图片展示给您,包括: ... -
Android Bitmap和Canvas学习笔记
2012-03-14 09:48 1219位图是我们开发中最常用的资源,毕竟一个漂亮的界面对用户是 ... -
android获取当前Canvas位图代码
2012-03-14 09:45 1626//获取位图代码 public Bitmap getC ... -
Android-NBA比分文直播
2012-03-09 22:27 1480由于上班时间需要关注NBA实况,又不能明目张胆地在上班时间打开 ... -
Android ProGuard实例教程
2011-12-19 10:21 5148ProGuard工具通过移除不用的代码,用语义上 ... -
掌上问答测试版
2011-12-13 13:17 8掌上问答android手机客户端,数据来源于天涯问答. ... -
完成足球资料库Android版
2011-11-17 17:12 1453APK下载地址:http://www.anzhi.com ... -
Android-为ListView增加Header
2011-11-14 09:34 1625原文链接:http://marshal.easymors ... -
Android ListView利用好convertView
2011-11-14 09:29 2330public View getView(int pos ... -
android中实现左右滑动View
2011-06-24 23:24 6192iphone中有很多应用都能够左右滑动,非常cool,关键是实 ... -
LiveScore1.4.0正式完成
2011-06-20 22:18 1138比分直播 主要功能:1.即时比分:全部、进行中、未开、完场2 ...
相关推荐
在Android平台上,流媒体播放远程MP3文件是一个常见的需求,特别是在音乐播放应用或者在线音频服务中。本示例代码提供了一种实现方式,通过下载并缓存一部分音频数据,然后利用`MediaPlayer`进行播放,实现了类似流...
### Android 实现流媒体播放远程MP3文件代码详解 #### 一、背景介绍与目标 在Android开发过程中,实现远程音频文件(如MP3)的流式播放是一项常见且实用的功能。本文档将深入探讨一个具体的实现案例,该案例通过...
在Android平台上,流媒体播放远程mp3文件是一个常见的需求,尤其在音乐应用或者在线音频服务中。本文将详细介绍如何在Android中实现这一功能,包括关键的步骤、使用的类和方法以及一些实现技巧。 首先,Android的...
在Android开发中,实现播放本地MP3和网络MP3音频是一项常见的需求,尤其在音乐类应用或者需要背景音效的应用中。本示例项目“Mp3demo”将详细阐述这一功能的实现步骤和关键技术。 首先,播放本地MP3文件通常涉及的...
在Android中,我们可以使用多种方式来播放MP3文件: 1. **MediaPlayer**:Android系统内置的`MediaPlayer`类是播放音频和视频的基本组件。它支持多种媒体格式,包括MP3。对于本地文件,可以直接使用`MediaPlayer....
流媒体播放程序是一种技术,它允许用户实时观看音频或视频内容,而无需等待整个文件下载完成。这种技术在互联网上广泛使用,因为它提高了用户体验,使用户可以即时观看内容,尤其适用于在线视频平台、直播服务以及...
`MediaPlayer`是Android中用于播放音频和视频的核心组件,它可以处理各种媒体源,如HTTP、RTSP流媒体、文件或内存中的数据。 2. **URL与IP地址转换**:描述中提到要将URL地址改成本机IP地址,这通常是因为在本地...
同时,实现媒体按钮的远程控制(如耳机上的播放/暂停键)也是必要的,这需要用到`RemoteControlClient`(API 16及以下)或`MediaSession`(API 21及以上)。 7. **权限管理**:考虑到Android的权限模型,音乐播放器...
创建一个MediaService可以实现播放控制并处理系统广播事件。 5. **Intent和BroadcastReceiver**: 为了实现远程控制(如锁屏界面、通知栏)的音乐播放,可以利用Intent和BroadcastReceiver。注册一个...
在Android平台上开发一款简易音乐播放器,涉及到许多关键的技术点,包括媒体库的访问、音频流处理、UI设计以及动画效果。以下是对这些知识点的详细解释: 1. **媒体库访问**:Android提供了MediaStore类,允许应用...
例如,`OnCompletionListener`可以监听歌曲播放结束,`OnErrorListener`可以捕获播放错误,`OnPreparedListener`则在媒体文件准备就绪后触发。 4. **UI设计**:音乐播放器通常需要一个友好的用户界面,包括播放/...
5. **网络连接需求**:由于依赖网络进行流媒体播放,因此,手机远程MP3播放器需要稳定且高速的网络环境。在Wi-Fi环境下,用户可以享受无损音质;而在移动数据下,应用可能会有适应性调整,如降低音频质量以节省流量...
MediaPlayer是Android平台上的核心组件,它支持多种音频格式,如MP3、AAC等,并且可以进行流媒体播放。开发者可以通过控制MediaPlayer的状态(如准备、播放、暂停、停止)来实现播放器的基本功能。 接下来,...
首先,我们要理解MP3播放器的基本功能,它需要能够处理本地存储的音乐文件以及在线流媒体服务。以下是对这个项目的一些详细说明: 1. **本地播放**:在Android设备上,MP3播放器首要的任务是能够读取并播放存储在SD...
`MediaPlayer`是Android提供的一个系统服务,用于播放各种类型的媒体文件和流媒体。它支持多种音频和视频格式,如MP3、AAC、MP4、3GP等,并且能够处理网络流媒体,使得在应用中集成在线播放成为可能。 下面我们将...
在IT领域,开发一个能够实现“简单地音乐播放,支持后台播放和远程控制及显示音乐信息”的应用是一项常见的任务。这个应用的核心功能包括音乐播放、后台运行能力以及远程控制,这些功能对于提升用户体验至关重要。 ...
这需要使用到Android的网络编程接口,如HttpURLConnection或者OkHttp库来下载或流式播放MP3文件。同时,需要理解HTTP协议和流媒体概念。 **3. Service组件** 为了在后台持续播放音乐,我们需要创建一个Service。...
- 可能包含一个`BroadcastReceiver`,监听媒体按钮事件(如耳机按键),实现对音乐播放的远程控制。 通过分析和学习Wind音乐播放器的源码,开发者可以掌握Android应用开发的基本流程,了解多媒体播放、数据存储、...
而`ExoPlayer`是Google官方推荐的高级播放器,它具有更强大的自定义能力,支持更多的格式和功能,如DASH和HLS流媒体协议。 2. **音频/视频解码**:Android支持多种编码格式,如MP3、AAC、MP4、FLV等。解码工作通常...