当前位置:编程学习 > wap >>

android远程试听mp3异常异常

在网上下载一段代码,发现只能播放一首歌曲,再次回到前一界面点击播放老是崩溃,大家帮忙看看是什么原因啊?
个人觉得应该是哪块的资源没释放,但是一直没找到
Android mediaplayer 异常 --------------------编程问答-------------------- package ntc.com.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.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;
}
} --------------------编程问答-------------------- public boolean startPlayer() {
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;
}
}
--------------------编程问答-------------------- 这段代码网上很多地方都有,说明可以试听远程MP3,大家有测试过的么? --------------------编程问答-------------------- 楼主贴报错吧,很多时候,可能是你手机底层抛出来的播放错误,不是程序的事情,应该是固件解码的事情 --------------------编程问答-------------------- 一直提示
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
补充:移动开发 ,  Android
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,