/** * Progressivly download the media to a temporary location and update the * MediaPlayer as new content becomes available. */ public void startStreaming(final String mediaUrl, float 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 { Log.d(TAG, " mediaUrl.replaceAll !");
URLConnection conn = new URL(mediaUrl).openConnection(); conn.addRequestProperty("User-Agent","NSPlayer/10.0.0.4072 WMFSDK/10.0"); conn.connect();
InputStream stream = conn.getInputStream(); Log.d(TAG, " conn.getInputStream !"); if (stream == null) { Log.e(getClass().getName(), "Unable to create InputStream for mediaUrl:" + mediaUrl); } downloadingMediaFile = new File(context + "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, "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(); } catch (IOException e) { Log.e(getClass().getName(), "Error initializing the MediaPlayer.", e); return; } } public boolean pausePlayer() { try { MediaPlayer media = getMediaPlayer(); if(null !=media ) { media.pause(); return true; }
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. Log.d(TAG, "FileInputStream !"); FileInputStream fis = new FileInputStream(mediaFile); Log.d(TAG, mediaFile.getName()); mPlayer.setDataSource(fis.getFD()); Log.d(TAG, "FileInputStream id over!"); mPlayer.prepare(); Log.d(TAG, "FileInputStream over!"); 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, "playingMedia" + counter + ".dat"); File bufferedFile = new File(context, "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. // Log.d(TAG, "bufferedFile.deleteOnExit() !"); 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. Log.d(TAG, "createMediaPlayer(bufferedFile) !"); mediaPlayer = createMediaPlayer(bufferedFile); Log.d(TAG, "seekTo(curPosition) !"); 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 Log.d(TAG, "mediaPlayer.start() !"); 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. Log.d(TAG, "oldBufferedFile.delete !"); 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() { float loadProgress = ((float) totalKbRead / (float) mediaLengthInKb); } }; 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(); } }; handler.post(updater); } // TODO 这个方法应该可以控制歌曲的播放 public MediaPlayer getMediaPlayer() { return mediaPlayer; } public void setCurrentTime(long musicLength) { String sTmp = ParseFunction.GetTimeForLocation(musicLength); this.textStreamed.setText(sTmp); Log.d(TAG, " current time" + sTmp); } public void startPlayProgressUpdater() { float progress = (((float) mediaPlayer.getCurrentPosition() / 1000) / mediaLengthInSeconds); progressBar.setProgress((int) (progress * 100)); if (mediaPlayer.getCurrentPosition() != mediaLengthInSeconds) { setCurrentTime(mediaPlayer.getCurrentPosition()); } else { setCurrentTime(((long) (mediaLengthInSeconds)) * 1000); progressBar.setProgress(100); } if (mediaPlayer.isPlaying()) { Runnable notification = new Runnable() { public void run() { startPlayProgressUpdater(); } }; handler.postDelayed(notification, 1000); } } public void interrupt() { 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"); 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"); player.reset(); player.start(); } 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; } }
一直提示 06-06 13:42:49.022: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0 06-06 13:42:49.022: E/MediaPlayer(9284): error (-38, 0) 06-06 13:42:49.022: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer 06-06 13:42:49.022: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0 06-06 13:42:49.092: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer 06-06 13:42:49.092: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0 06-06 13:42:49.092: E/MediaPlayer(9284): error (-38, 0) 06-06 13:42:49.122: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer 06-06 13:42:49.122: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0 06-06 13:42:49.122: E/MediaPlayer(9284): error (-38, 0) 06-06 13:42:49.122: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer 06-06 13:42:49.122: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0 06-06 13:42:49.122: E/MediaPlayer(9284): error (-38, 0) 06-06 13:42:49.152: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer 06-06 13:42:49.152: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0 06-06 13:42:49.152: E/MediaPlayer(9284): error (-38, 0) 06-06 13:42:49.152: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
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.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.text.TextUtils;
import android.text.format.Time;
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
Time tm;
private static final String TAG = "StreamingMediaPlayer"; private TextView textStreamed;
private ImageButton playButton;
private ProgressBar progressBar;
// Track for display by progressBar
private float 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 String 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()
{}
public StreamingMediaPlayer(String context, TextView textStreamed,
ImageButton playButton, Button streamButton, ProgressBar progressBar) {
this.context = context;
this.textStreamed = textStreamed;
this.playButton = playButton;
this.progressBar = progressBar;
} public void setStreamingMediaPlayer(String 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, float 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 {
Log.d(TAG, " mediaUrl.replaceAll !");
// URL url = new URL(mediaUrl.replaceAll(" ", "%20"));
// HttpURLConnection conn = (HttpURLConnection) url.openConnection();
URLConnection conn = new URL(mediaUrl).openConnection();
conn.addRequestProperty("User-Agent","NSPlayer/10.0.0.4072 WMFSDK/10.0");
conn.connect();
InputStream stream = conn.getInputStream();
Log.d(TAG, " conn.getInputStream !");
if (stream == null) {
Log.e(getClass().getName(),
"Unable to create InputStream for mediaUrl:" + mediaUrl);
} downloadingMediaFile = new File(context + "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, "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();
} catch (IOException e) {
Log.e(getClass().getName(), "Error initializing the MediaPlayer.",
e);
return;
}
} public boolean pausePlayer() {
try {
MediaPlayer media = getMediaPlayer();
if(null !=media )
{
media.pause();
return true;
}
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
MediaPlayer media = getMediaPlayer();
if(null !=media )
{
media.start();
startPlayProgressUpdater();
return true;
}
Log.d(TAG, " getMediaPlayer().start() !");
return false;
} public void stopPlayer() {
MediaPlayer media = getMediaPlayer();
try {
if(null !=media )
{
media.stop();
addforEnd();
}
} catch (Exception e) {
e.printStackTrace();
}
} public void addforEnd()
{
try {
deleteTmpFile(this.context, true);
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater();
}
};
handler.postDelayed(notification, 1000);
}
}
catch (Exception e) {
Log.d(TAG, " addforEnd" + e.getMessage());
e.printStackTrace();
}
}
private void deleteTmpFile(String filePath, boolean deleteThisPath)
throws IOException{
if (!TextUtils.isEmpty(filePath)) {
File file = new File(filePath);
if (file.isDirectory()) {// 处理目录
File files[] = file.listFiles();
for (int i = 0; i < files.length; i++) {
deleteTmpFile(files[i].getAbsolutePath(), true);
}
}
if (deleteThisPath) {
if (!file.isDirectory()) {// 如果是文件,删除
file.delete();
}
}
}
}
/**
* 根据文件创建一个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.
Log.d(TAG, "FileInputStream !");
FileInputStream fis = new FileInputStream(mediaFile);
Log.d(TAG, mediaFile.getName());
mPlayer.setDataSource(fis.getFD());
Log.d(TAG, "FileInputStream id over!");
mPlayer.prepare();
Log.d(TAG, "FileInputStream over!");
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, "playingMedia" + counter
+ ".dat");
File bufferedFile = new File(context, "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.
// Log.d(TAG, "bufferedFile.deleteOnExit() !");
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.
Log.d(TAG, "createMediaPlayer(bufferedFile) !");
mediaPlayer = createMediaPlayer(bufferedFile);
Log.d(TAG, "seekTo(curPosition) !");
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
Log.d(TAG, "mediaPlayer.start() !");
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.
Log.d(TAG, "oldBufferedFile.delete !");
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() {
float loadProgress = ((float) totalKbRead / (float) mediaLengthInKb);
}
};
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();
}
};
handler.post(updater);
} // TODO 这个方法应该可以控制歌曲的播放
public MediaPlayer getMediaPlayer() { return mediaPlayer;
} public void setCurrentTime(long musicLength) {
String sTmp = ParseFunction.GetTimeForLocation(musicLength); this.textStreamed.setText(sTmp);
Log.d(TAG, " current time" + sTmp);
} public void startPlayProgressUpdater() {
float progress = (((float) mediaPlayer.getCurrentPosition() / 1000) / mediaLengthInSeconds); progressBar.setProgress((int) (progress * 100)); if (mediaPlayer.getCurrentPosition() != mediaLengthInSeconds) {
setCurrentTime(mediaPlayer.getCurrentPosition());
} else {
setCurrentTime(((long) (mediaLengthInSeconds)) * 1000);
progressBar.setProgress(100);
} if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater(); }
};
handler.postDelayed(notification, 1000);
}
} public void interrupt() {
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");
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");
player.reset();
player.start();
} 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;
}
}
06-06 13:42:49.022: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
06-06 13:42:49.022: E/MediaPlayer(9284): error (-38, 0)
06-06 13:42:49.022: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
06-06 13:42:49.022: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
06-06 13:42:49.092: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
06-06 13:42:49.092: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
06-06 13:42:49.092: E/MediaPlayer(9284): error (-38, 0)
06-06 13:42:49.122: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
06-06 13:42:49.122: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
06-06 13:42:49.122: E/MediaPlayer(9284): error (-38, 0)
06-06 13:42:49.122: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
06-06 13:42:49.122: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
06-06 13:42:49.122: E/MediaPlayer(9284): error (-38, 0)
06-06 13:42:49.152: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
06-06 13:42:49.152: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
06-06 13:42:49.152: E/MediaPlayer(9284): error (-38, 0)
06-06 13:42:49.152: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer