2017-06-17 3 views
0

Hallo ich baue ein natives Android-Modul für Musik-Streaming reagieren. Wenn ich versuche, Musik zu streamen, funktioniert sie mit der ersten URL, die ich lade, aber wenn ich versuche, eine andere URL zu laden, stürzt die App ab.Android Musik Streamer

Hier ist der Code für das Modul.

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; 

     } 
    } 
} 

Es gibt eine Seite, die die Lieder und ihre URLs hat. Wenn ich einen Song auf der ersten Seite auswähle, navigiert er zur zweiten Seite mit der URL des Songs. Hier ist der JS-Code für die zweite Seite (die Seite, die die Songs spielt):

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

EDIT: Hier ist die 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 

Antwort

1

Es könnte, weil das nächste Mal abstürzt, wenn Sie Second Song spielen, es könnte "NULL" Objekt von Mediaplayer bekommen. Bitte posten Sie Ihren Logcat mit Abstürzen, damit ich mich sicherer auf meine Antwort verlassen kann.

+0

ich hinzugefügt haben die logcat – digiwebguy

+0

"Boolean vorbereitet = false; " entferne diese Zeile von "doInBackground()". Der Media Player kann nicht wie bei "public void play (String url)" zurückgesetzt werden, da "prepare" immer "false" bleibt. Durch das Entfernen über die Zeile wird direkt auf Ihre globale "Vorbereitung" zugegriffen. –

+0

Danke. Ich weiß nicht, wie ich das vermisst habe. Ich habe es entfernt, aber es stürzt immer noch ab:/ – digiwebguy

0

@Rahul Guptas Kommentare brachten mich dazu, über das Problem in der richtigen Weise nachzudenken. Das Problem war also, dass ich den Check am falschen Ort gemacht habe. Alles was ich tun musste, war den if (prepared) else Block in meine asynchrone Aufgabe zu verschieben und das Problem zu lösen. Hier ist der Code:

Dies ist, was das Spiel Methode sieht aus wie jetzt:

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

und hier ist die ASYNC Aufgabe:

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

    } 
}