我有一个奇怪的问题。我正在尝试开发简单的应用程序,播放在线广播。所以我有7个频道。当我从设备测试它们时,流媒体在2分钟后停止(它立即开始)。但是当我在eclipse模拟器上播放它时,它会在20分钟后停止。请帮助我。我不希望流式传输停止,直到用户想要。 这是我的第一堂课的代码
import java.io.IOException;
import com.pocketjourney.media.StreamingMediaPlayer;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.VideoView;
public class HelloInterruptVideoStream extends Activity implements
OnClickListener {
private String path = null;
// "http://192.168.9.59:8000/m3.mp3"
private VideoView video_view_;
StreamingMediaPlayer audioStreamer;
private Button room1, room2, room3, room4, room5, room6, room7;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.live_rooms);
video_view_ = (VideoView) findViewById(R.id.surface_view);
room1 = (Button) findViewById(R.id.Room1);
room2 = (Button) findViewById(R.id.Room2);
room3 = (Button) findViewById(R.id.Room3);
room4 = (Button) findViewById(R.id.Room4);
room5 = (Button) findViewById(R.id.Room5);
room6 = (Button) findViewById(R.id.Room6);
room7 = (Button) findViewById(R.id.Room7);
room1.setOnClickListener(this);
room2.setOnClickListener(this);
room3.setOnClickListener(this);
room4.setOnClickListener(this);
room5.setOnClickListener(this);
room6.setOnClickListener(this);
room7.setOnClickListener(this);
}
public void startStreaming(String path) {
try {
if (audioStreamer != null) {
audioStreamer.interrupt();
}
audioStreamer = new StreamingMediaPlayer(this);
// audioStreamer.startStreaming("http://www.pocketjourney.com/downloads/pj/tutorials/audio.mp3",1717,
// 214);
audioStreamer.startStreaming(path, 5208);
} catch (IOException e) {
Log.e(getClass().getName(), "Error starting to stream audio.", e);
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.Room1) {
startStreaming("http*******************");
}
else if (v.getId() == R.id.Room2) {
startStreaming("http*******************");
}
else if (v.getId() == R.id.Room3) {
startStreaming("http*******************");
}
else if (v.getId() == R.id.Room4) {
startStreaming("http*******************");
}
else if (v.getId() == R.id.Room5) {
startStreaming("http*******************");
}
else if (v.getId() == R.id.Room6) {
startStreaming("http*******************");
}
else if (v.getId() == R.id.Room7) {
startStreaming("http*******************");
}
}
}
我的第二个活动
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 com.elhaso.tutinterruptvideostream.R;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.VideoView;
public class StreamingMediaPlayer {
private static final int INTIAL_KB_BUFFER = 128*10/8;//assume 96kbps*10secs/8bits per byte
// Track for display by progressBar
private int totalKbRead = 50;
// 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;
public StreamingMediaPlayer(Context context)
{
this.context = context;
}
/**
* 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) throws IOException {
Runnable r = new Runnable() {
public void run() {
try {
Log.d("Runable", " Downloading audio here ");
downloadAudioIncrement(mediaUrl);
} catch (IOException e) {
Log.e(getClass().getName(), "Unable to initialize the MediaPlayer for fileUrl=" + mediaUrl, e);
return;
}
}
};
new Thread(r).start();
Log.d("Thread start ","Thread startig ");
}
/**
* 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.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.mp3");
// 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);
Log.d("FileOutputStream", "Creating a buffer and downloading a file");
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;
Log.d("Testing Buffer","Buffer is created now testing it ");
testMediaBuffer();
fireDataLoadUpdate();
} while (validateNotInterrupted());
stream.close();
Log.d("Not Interrupted","Closing Stream ");
if (validateNotInterrupted()) {
fireDataFullyLoaded();
}
}
private boolean validateNotInterrupted() {
Log.d("Validate Not Interrupted","Media player pause ");
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 {
Log.d("Starting Media Player","Media Player starting ");
startMediaPlayer();
Log.d("Started Media Player","Media Player started");
} catch (Exception e) {
Log.e(getClass().getName(), "Error copying buffered conent.", e);
}
}
} else if ( mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000 ){
Log.d("Get Duration","Getting Current Position");
// 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();
Log.d("Buffer is Transfered to Media player","Buffered Media Player");
}
}
};
handler.post(updater);
}
private void startMediaPlayer() {
try {
Log.d("Start Media Player","Starting Media Player ");
File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat");
Log.d("Media player started"," Media Player started ");
// 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;
}
}
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());
Log.d("Preparing Media Player","Media Player Prepared ");
mPlayer.prepare();
return mPlayer;
}
/**
* 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){
Log.d("At the end of the file","Media player Starting");
mediaPlayer.start();
Log.d("Media Player start","Media Player started");
}
// 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() {
}
};
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();
Log.d("Deleting Media file","Media File deleted ");
}
};
handler.post(updater);
}
public MediaPlayer getMediaPlayer() {
return mediaPlayer;
}
public void startPlayProgressUpdater() {
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() );
}
}
}