Android音乐流光

时间:2017-06-17 05:06:42

标签: javascript android react-native

嗨,我正在构建一个用于音乐流的反应原生android模块。当我尝试流式传输音乐时,它会使用我加载的第一个网址,但是当我尝试加载其他网址时,该应用会崩溃。

这是模块的代码。

package com.mediaplayer;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.AsyncTask;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import java.io.IOException;

public class MediaPlayerModule extends ReactContextBaseJavaModule {
    String stream = "http://stream.radioreklama.bg:80/radio1rock128";
    boolean prepared = false;
    boolean started = false;

    MediaPlayer mediaPlayer;
    PlayerTask playerTask;

    public MediaPlayerModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    }

    @Override
    public String getName() {
        return "MediaPlayerModule";
    }


    @ReactMethod
    public void play(String url) {
        if(prepared){
            mediaPlayer.reset();
            mediaPlayer.release();
        }
        playerTask = new PlayerTask();
        playerTask.execute(url);
    }


    @ReactMethod
    public void pause() {

        if(mediaPlayer != null){
            mediaPlayer.reset();
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    @ReactMethod
    public void resume() {
         if (started) {
            mediaPlayer.start();
         }
    }

    @ReactMethod
    public void destroy() {
         if (prepared) {
            mediaPlayer.release();
             started = false;
         }
    }

    class PlayerTask extends AsyncTask<String, Void, Boolean> {
        @Override
        protected Boolean doInBackground(String... strings) {
            Boolean prepared = false;

                try {
                    mediaPlayer.setDataSource(strings[0]);
                    mediaPlayer.prepare();
                    prepared = true;
                } catch (IOException e) {
                    e.printStackTrace();
                    prepared = false;
                }

            return prepared;
        }

        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute(aBoolean);
            mediaPlayer.start();
            started = true;

        }
    }
}

有一个页面包含歌曲及其网址。当我在第一页上选择一首歌曲时,它会使用歌曲的URL导航到第二页。这是第二页(播放歌曲的页面)的js代码:

var mp = require('react-native').NativeModules.MediaPlayerModule;

export default class Player extends Component {

    constructor(props) {
        super(props);
        this.state = {
            image: this.props.navigation.state.params.image,
            title: this.props.navigation.state.params.title,
            artistes: this.props.navigation.state.params.artistes,
            mp3Url:this.props.navigation.state.params.mp3Url
        }
    }

    componentDidMount(){
        mp.play(this.state.mp3Url);
    }
}

编辑:这是logcat:

    --------- beginning of crash
06-17 07:21:28.544 2406-2432/com.downstream E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
                                                              Process: com.downstream, PID: 2406
                                                              java.lang.RuntimeException: An error occurred while executing doInBackground()
                                                                  at android.os.AsyncTask$3.done(AsyncTask.java:309)
                                                                  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
                                                                  at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
                                                                  at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                                                                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                  at java.lang.Thread.run(Thread.java:818)
                                                               Caused by: java.lang.IllegalStateException
                                                                  at android.media.MediaPlayer.nativeSetDataSource(Native Method)
                                                                  at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1085)
                                                                  at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1046)
                                                                  at com.mediaplayer.MediaPlayerModule$PlayerTask.doInBackground(MediaPlayerModule.java:118)
                                                                  at com.mediaplayer.MediaPlayerModule$PlayerTask.doInBackground(MediaPlayerModule.java:112)
                                                                  at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                                  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
                                                                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
                                                                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                                                                  at java.lang.Thread.run(Thread.java:818) 
06-17 07:21:28.914 2406-2428/com.downstream E/Surface: getSlotFromBufferLocked: unknown buffer: 0xae6b5f10

2 个答案:

答案 0 :(得分:1)

它可能会崩溃,因为下次播放第二首歌时,它可能会出现&#34; NULL&#34; Mediaplayer的对象。请在崩溃时发布你的logcat,这样我就能更加确定我的答案。

答案 1 :(得分:0)

@Rahul Gupta的评论让我以正确的方式思考问题。所以问题是我正在检查准备在错误的地方。我需要做的就是将if(准备好的)else块移动到我的异步任务中,它解决了问题。这是代码:

这就是play方法现在的样子:

@ReactMethod
public void play(String url) {
    playerTask = new PlayerTask();
    playerTask.execute(url);
}

这是ASYNC任务:

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

        if(prepared){
            mediaPlayer.reset();
        }

        try {
            mediaPlayer.setDataSource(strings[0]);
            mediaPlayer.prepare();
            mediaPlayer.start();
            prepared = true;
        } catch (IOException e) {
            e.printStackTrace();
            prepared = false;
        }

        return prepared;
    }

    @Override
    protected void onPostExecute(Boolean aBoolean) {
        super.onPostExecute(aBoolean);

    }
}