【问题标题】:Android: prepareAsync() during audio streaming delayAndroid:音频流延迟期间的 prepareAsync()
【发布时间】:2017-07-23 21:55:55
【问题描述】:

我正在尝试从以下网址播放音频:http://mtl2.liveatc.net/lbbg 这是我的代码:

public void setConnection(String url) {
    String url = http://mtl2.liveatc.net/lbbg;
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    new Player().execute(url);
}

private class Player extends AsyncTask<String, Void, Void> {
    @Override
    protected Void doInBackground(String... strings) {

        try {
            mediaPlayer.setDataSource(strings[0]);
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mediaPlayer) {
                    mediaPlayer.stop();
                    mediaPlayer.reset();
                }
            });

            mediaPlayer.prepareAsync();

        } catch (Exception e) {
            Log.e("MyAudioStreamingApp", e.getMessage());
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){

            @Override
            public void onPrepared(MediaPlayer mp) {
                progressBar.setVisibility(View.INVISIBLE);
                mp.start();
            }
        });

    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressBar.setVisibility(View.VISIBLE);
    }
}

一切正常,但延迟非常大。如果我在浏览器中打开这个 url,开始流式传输需要将近 20 秒,但是当我在我的应用程序中运行它时,需要 5-7 分钟。

UPD 还添加我的日志:

07-24 01:12:52.820 25918-25961/com.example I/OpenGLRenderer: Initialized EGL, version 1.4
07-24 01:12:52.843 25918-25961/com.example E/HAL: hw_get_module_by_class: module name gralloc
07-24 01:12:52.843 25918-25961/com.example E/HAL: hw_get_module_by_class: module name gralloc
07-24 01:12:59.171 25918-25918/com.example E/ExtMediaPlayer-JNI: env->IsInstanceOf fails
07-24 01:12:59.171 25918-25918/com.example E/MediaPlayer-JNI: JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
07-24 01:12:59.171 25918-25918/com.example E/ExtMediaPlayer-JNI: env->IsInstanceOf fails
07-24 01:12:59.171 25918-25918/com.example E/MediaPlayer-JNI: JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
07-24 01:12:59.188 25918-25931/com.example D/MediaHTTPConnection: filterOutInternalHeaders: key=User-Agent, val= stagefright/1.2 (Linux;Android 6.0.1)
07-24 01:12:59.191 25918-26002/com.example D/MediaHTTPConnection: proxy null port 0
07-24 01:12:59.192 25918-26002/com.example I/DpmTcmClient: RegisterTcmMonitor from: com.android.okhttp.TcmIdleTimerMonitor
07-24 01:15:42.557 25918-25925/com.example W/art: Suspending all threads took: 31.418ms
07-24 01:17:48.107 25918-25918/com.example D/MediaPlayer: setSubtitleAnchor in MediaPlayer

UPD2:我的“解决方案”:我找不到这个问题的解决方案,所以我决定使用下一件事:我把小的 WebView 放在那里我需要播放按钮,并收到完整的音频播放器在 10-15 秒内加载和播放此流。

【问题讨论】:

    标签: android android-mediaplayer audio-streaming


    【解决方案1】:

    检查你的线程优先级。

    Thread.currentThread().getPriority();
    

    根据我的经验,当 mediaPlayer 在 AsyncTask 等工作线程中准备或启动时,一些旧的(Android 5~6)设备(例如:LG..)会出现此类问题。在这种情况下,将优先级设置得更高或使用主线程。就我而言,将 prepareAsync 移至主线程。

    更新

    我测试了代码,发现优先级不是问题。我认为 Android mediaPlayer 不是“那个”网址的好选择。我曾经为流媒体项目选择 ffmpeg 或 google/exoplayer。

    响应头

    HTTP/1.1 200 OK
    Server: nginx/1.12.1
    Content-Type: audio/mpeg
    Connection: close
    icy-br: 16
    ice-audio-info: ice-samplerate=11025;ice-bitrate=16;ice-channels=1
    icy-br: 16
    icy-description: LBBG Burgas, Bulgaria
    icy-genre: ATC
    icy-name: Burgas Tower, Approach
    icy-private: 0
    icy-pub: 1
    icy-url: http://www.liveatc.net
    ...
    

    媒体信息

    Input #0, mp3, from 'http://mtl2.liveatc.net/lbbg':
    Duration: N/A, start: 0.000000, bitrate: 16 kb/s
    Stream #0.0: Audio: mp3, 11025 Hz, mono, s16, 16 kb/s
    

    【讨论】:

    • 我在 Kotlin 项目中使用 ExoPlayer 从 Shoutcast 流式传输广播音乐,效果非常好。我在使用 MediaPlayer 时遇到了同样的延迟问题。
    【解决方案2】:

    不使用任务,你可以简单地做到:

    MediaPlayer mediaPlayer = new MediaPlayer();
    
    mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
        public boolean onError(MediaPlayer mp, int what, int extra) {
            mp.reset();
            return false;
        }
    });
    
    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });
    
    try {
        mediaPlayer.setDataSource("http://yoururl");
        mediaPlayer.prepareAsync();
    } catch (IllegalArgumentException e) {
    } catch (IllegalStateException e) {
    } catch (IOException e) {
    }
    

    试试这个简单的方法,检查延迟是否仍然存在。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 2013-06-12
    • 2013-12-15
    • 2016-07-07
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    相关资源
    最近更新 更多