Android - 具有渐进式流媒体的视频视图

时间:2013-10-07 09:42:53

标签: android streaming video-streaming android-videoview

StreamingMediaPlayer .java           MediaPlayer尚不支持从外部URL流式传输,因此该类提供了伪流功能           通过逐步下载内容&我们在临时存储中获得足够的音频后立即播放。

但代码报告错误......它没有播放视频,只是显示流进度

    public class StreamingMediaPlayer {

                        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;//mediaplayer

                    private File downloadingMediaFile; //old location

                    private boolean isInterrupted;

                    private Context context;

                    private int counter = 0;

                    public StreamingMediaPlayer(Context  context,TextView textStreamed, ImageButton playButton, Button  streamButton,ProgressBar    progressBar) 
                    {
                        this.context = context;
                        this.textStreamed = textStreamed;
                        this.playButton = playButton;
                        this.progressBar = progressBar;
                    }

                    /**  
                     * Progressively 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;

                        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();
                    }

                    /**  
                     * 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_" + (counter++) + ".dat");
                        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");
                            moveFile(downloadingMediaFile,bufferedFile);

                            Log.e("Player",bufferedFile.length()+"");
                            Log.e("Player",bufferedFile.getAbsolutePath());

                            mediaPlayer = new MediaPlayer();
                            mediaPlayer.setDataSource(bufferedFile.getAbsolutePath());
                            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                            mediaPlayer.prepareAsync();
                            fireDataPreloadComplete();

                        } catch (IOException e) {
                            Log.e(getClass().getName(), "Error initializing the MediaPlaer.", e);
                            return;
                        }   
                    }

                    /**
                     * 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 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();
                            mediaPlayer.pause();

                            File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat");
                            //FileUtils.copyFile(downloadingMediaFile,bufferedFile);

                            mediaPlayer = new MediaPlayer();
                            mediaPlayer.setDataSource(bufferedFile.getAbsolutePath());
                            //mediaPlayer.setAudioStreamType(AudioSystem.STREAM_MUSIC);
                            mediaPlayer.prepareAsync();
                            mediaPlayer.seekTo(curPosition);

                            //  Restart if at end of prior beuffered 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();
                            }
                        }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((CharSequence) (totalKbRead + " Kb read"));
                                float loadProgress = ((float)totalKbRead/(float)mediaLengthInKb);
                                progressBar.setSecondaryProgress((int)(loadProgress*100));
                            }
                        };
                        handler.post(updater);
                    }

                    /**
                     * We have preloaded enough content and started the MediaPlayer so update the buttons & progress meters.
                     */
                    private void fireDataPreloadComplete() {
                        Runnable updater = new Runnable() {
                            public void run() {
                                mediaPlayer.start();
                                startPlayProgressUpdater();
                                playButton.setEnabled(true);
                                //streamButton.setEnabled(false);
                            }
                        };
                        handler.post(updater);
                    }

                    private void fireDataFullyLoaded() {
                        Runnable updater = new Runnable() { 
                            public void run() {
                                transferBufferToMediaPlayer();
                                textStreamed.setText((CharSequence) ("Audio full loaded: " + totalKbRead + " Kb read"));
                            }
                        };
                        handler.post(updater);
                    }

                    public MediaPlayer getMediaPlayer() {
                        return mediaPlayer;
                    }

                    public void startPlayProgressUpdater() {
                        float progress = (((float)mediaPlayer.getCurrentPosition()/1000)/(float)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();
                    }

                    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() );
                        }
                    }
                }


    //java file

    /*main activity*/
    /* tutorial 3*/
    package com.example.tutorial;

    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.MediaController;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.VideoView;

    public class Tutorial3 extends Activity {
        //VideoView videoView;
        private Button streamButton;

        private ImageButton playButton;

        private TextView textStreamed;

        private boolean isPlaying;

        private StreamingMediaPlayer audioStreamer;

        public void onCreate(Bundle icicle) {

            super.onCreate(icicle);

            setContentView(R.layout.tutorial3);
            initControls();


        } 

        private void initControls() {
            textStreamed = (TextView) findViewById(R.id.text_kb_streamed);
            streamButton = (Button) findViewById(R.id.button_stream);
            //videoView = (VideoView) findViewById(R.id.VideoView);

            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 ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar);
                if ( audioStreamer != null) {
                    audioStreamer.interrupt();
                }
                    audioStreamer = new StreamingMediaPlayer(this,textStreamed, playButton, streamButton,progressBar);
                audioStreamer.startStreaming("http://www.boisestatefootball.com/sites/default/files/videos/original/01%20-%20coach%20pete%20bio_4.mp4",1677, 214);
                //streamButton.setEnabled(false);
            } catch (IOException e) {
                Log.e(getClass().getName(), "Error starting to stream audio.", e);                  
            }

        }
    }    


    //XML file 



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:padding="10px" >

    <TextView
        android:id="@+id/text_kb_streamed"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Streaming .mp3 Audio Tutorial"
        android:textStyle="bold" />

    <Button
        android:id="@+id/button_stream"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10px"
        android:text="Start Streaming" />

    <ProgressBar
        android:id="@+id/progress_bar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="200px"
        android:layout_height="wrap_content" />

    <ImageButton
        android:id="@+id/button_play"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5px"
        android:src="@drawable/button_pause" />


</LinearLayout>        

以上代码报告了一些未知错误,如错误(-38,0)

0 个答案:

没有答案