使用RTSP网址的Andr​​oid 4.0.4的MediaPlayer prepare问题网址、问题、Andr、RTSP

2023-09-06 03:27:17 作者:独守空房丶为等伊人笑

我遇到了视频流应用程序我工作的一个奇怪的问题。视频/音频的实际数据流是工作的罚款对我所有的测试设备。然而,看似任何设备4.0+上,使用RTSP URL,prepare()时,立即返回(这将导致一个问题,提供适当的信息反馈给用户,而视频加载并干扰其他几个系统我已经制定)。

下面是code,我初始化和设置我的MediaPlayer块,但保留了几件事:

在我的initPlayer方法是从AsyncTask的调用。 视频最终会正常播放,但prepare立即返回创建过程中的视频负载缺乏反馈给用户。 在整个过程中发生任何形式的错误 在启动()通过在$ P $我在preparedListener,这显然成为一个问题时,prepare()返回它实际上是准备进行播放ppared方法被调用的MediaPlayer的。 在HTTP流似乎做工精细,低于4.0每个测试设备上的问题不会发生。

我一直在试图解决这一问题的时间可笑的量,而一直没能找到其他人谁也碰到了这个问题。任何想法将大大AP preciated。

 公共无效initPlayer(){
        //我们首先需要确保的MediaPlayer不为空
        如果(mMediaPlayer == NULL){
            mMediaPlayer =新的MediaPlayer();
            mMediaPlayer.setOn preparedListener(媒体播放器preparedListener);
            mMediaPlayer.setOnCompletionListener(mediaPlayerCompletionListener);
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
        //如果视频/流已被选定,而另一个已经被打
        否则如果(mMediaPlayer.isPlaying()){
            mMediaPlayer.reset();
        }
        //视频是不是在全屏模式
        第二= FALSE;
        尝试 {
            mMediaPlayer.setDataSource(videoString);
            持有人= M preview.getHolder();
            mMediaPlayer.setDisplay(保持器);
            mMediaPlayer prepare()。
        }赶上(抛出:IllegalArgumentException E){
            e.printStackTrace();
        }赶上(SecurityException异常E){
            e.printStackTrace();
        }赶上(IllegalStateException异常E){
            e.printStackTrace();
        }赶上(IOException异常E){
            e.printStackTrace();
        }
    }

    //在preparedListener
    私人preparedListener媒体播放器preparedListener =新在preparedListener(){
        公共无效于prepared(MediaPlayer的MP){
            mp.start();
            vidPb.setVisibility(View.INVISIBLE);
        }
    };
 

解决方案

使用的 MP。prepareAsync() ,因为它是流媒体更好。使用 prepare()块,直到MediaPlayer的准备回放或一个IllegalStateException发生。此外,在安卓4.0(ICS),阻断任何UI线程更是严格,可能会导致ANR(活动不响应)对话框出现。

最后一个想法,尽量避免使用 e.printStackTrace();在Android应用程序。 相反,使用 Log.e(为tag_string,e.getMessage(),E); 打印错误,你可以从的 的logcat 。

所有的一切,它应该看起来是这样的:

 尝试{
        mMediaPlayer.setDataSource(videoString);
        持有人= M preview.getHolder();
        mMediaPlayer.setDisplay(保持器);
        。mMediaPlayer prepareAsync();
    }赶上(抛出:IllegalArgumentException E){
        Log.e(为tag_string,e.getMessage(),E);
    }赶上(SecurityException异常E){
        Log.e(为tag_string,e.getMessage(),E);
    }赶上(IllegalStateException异常E){
        Log.e(为tag_string,e.getMessage(),E);
    }赶上(IOException异常E){
        Log.e(为tag_string,e.getMessage(),E);
    }
 

I am experiencing an odd issue with a video streaming application I am working on. The actual streaming of video/audio is working fine on all of my test devices. However, on seemingly any device 4.0+, when using an RTSP URL, prepare() returns instantly (this causes an issue providing proper feedback to the users while a video is loading and interferes with a few other systems I have in place).

Below is the block of code where I initialize and setup my MediaPlayer, but keep a few things in mind:

My initPlayer method is called from an AsyncTask. The video does eventually play correctly, but prepare returning instantly creates a lack of feedback to the user during a video load. No errors of any kind occur during the entire process start() is called on the MediaPlayer via the onPrepared method in my OnPreparedListener, which obviously becomes an issue when prepare() returns before it is actually ready to be played. HTTP streams seem to work fine, and on every test device below 4.0 the issue does not occur.

I have been trying to fix this for a ridiculous amount of time, and haven't been able to find anyone else who has ran into this problem. Any ideas would be greatly appreciated.

    public void initPlayer() {
        //We first need to make sure the MediaPlayer isn't null
        if(mMediaPlayer==null){
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setOnPreparedListener(mediaPlayerPreparedListener);
            mMediaPlayer.setOnCompletionListener(mediaPlayerCompletionListener);
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
        //If a video/stream has been chosen while another is already playing
        else if(mMediaPlayer.isPlaying()){
            mMediaPlayer.reset();
        }
        //Video is not in full screen mode
        second = false;
        try {
            mMediaPlayer.setDataSource(videoString);
            holder = mPreview.getHolder();
            mMediaPlayer.setDisplay(holder);
            mMediaPlayer.prepare();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //onPreparedListener
    private OnPreparedListener mediaPlayerPreparedListener = new OnPreparedListener(){
        public void onPrepared(MediaPlayer mp) {
            mp.start();
            vidPb.setVisibility(View.INVISIBLE);
        }
    };

解决方案

Use mp.prepareAsync() as it is better for streaming media. Using prepare() blocks until MediaPlayer is ready for playback or an IllegalStateException occurs. Also, in android 4 (ICS), blocking on any UI thread is even more strict and may cause an ANR (Activity not responding) dialog to appear.

One final thought, try to avoid using e.printStackTrace(); in android apps. Instead, use the Log.e("TAG_STRING", e.getMessage(), e); to print errors to the android logging system that you can access from logcat.

All in all, it should looks something like this:

    try {
        mMediaPlayer.setDataSource(videoString);
        holder = mPreview.getHolder();
        mMediaPlayer.setDisplay(holder);
        mMediaPlayer.prepareAsync();
    } catch (IllegalArgumentException e) {
        Log.e("TAG_STRING", e.getMessage(), e);
    } catch (SecurityException e) {
        Log.e("TAG_STRING", e.getMessage(), e);
    } catch (IllegalStateException e) {
        Log.e("TAG_STRING", e.getMessage(), e);
    } catch (IOException e) {
        Log.e("TAG_STRING", e.getMessage(), e);
    }