2017-06-29 4 views
0

アンドロイドアプリを作って、ローカルWi-Fiネットワークからボイスをストリームします。私はJNIでOpus C APIを使ってデコードし、OpenSL Audioで読み込みます。AndroidでOpenSLオーディオをロックすると画面がロックされます。5.0.1 OK 6.0.1 Not OK

私はServiceからJNIを呼びます。

public class StreamService extends Service { 

     private NativeReceiver mNativeReceiver; 
... 

@Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     // Gérer la requête 
     mNativeReceiver = new NativeReceiver(); 
     mCanPlay = mNativeReceiver.init(); 
      mNativeReceiver.startNativeReceiver(); 
    ...   
    return Service.START_NOT_STICKY; 
} 

私のボタンをクリックすると、このサービスが呼び出され、自分のAndroidスマートフォンから音が出ます。

しかし、スマートフォンの画面をロックすると、サウンドが再生されているときにロックが解除されると、音が「ミュート」のようになります。 6.0.Xではなく5.0.Xで

私の最初の考えはネットワークパケットが停止していたので、デバッグを行い、スマートフォンはネットワークパケットを受信し続けます。

マイサービスが動作していて、音がミュートされています。

public void startNativeReceiver() { 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
       // set priority 
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 
       start(); 
      } 
     }).start(); 
    } 

そして、それは、これを呼び出す:

const int queue_elements_num = 20; 
    const int start_after = 4; 
    SpscCircularQueue *queue = NULL; 

    OpusDecoder *opus_dec = NULL; 
    uint32_t samplerate = 24000; 
    float frame_length = 20; 

    bool player_initialized = false; 
    bool player_started = false; 
    int frames_in_queue = 0; 

    while (!rcv_th_terminate) { 
     ssize_t rcv_len = read(udp_sock, rcv_buf, sizeof(rcv_buf)); 
     if (rcv_len <= 0) { 
      __android_log_print(ANDROID_LOG_WARN, "SMPlayer", 
          "Failed to receive UDP data"); 
      continue; 
     } 
     __android_log_print(ANDROID_LOG_INFO, "SMPlayer", 
          "reading"); 
     if (!player_initialized) { 
      if (rcv_buf[0] != 0x01) { 
       __android_log_print(ANDROID_LOG_ERROR, "SMPlayer", 
            "Unsupported version of SMPlayer " 
            "streaming protocol"); 
       return NULL; 
      } 
      /* initialize decoder */ 
      int opus_err = 0; 
      opus_dec = opus_decoder_create(samplerate, 1, &opus_err); 
      if (!opus_dec) { 
       __android_log_print(ANDROID_LOG_ERROR, "SMPlayer", 
            "unable to initialize OPUS decoder, " 
            "error code - %d", opus_err); 
       return NULL; 
      } 

      /* initialize circular queue */ 
      uint32_t frame_buf_size = samplerate/1000 * frame_length * 2; 
      queue = spsc_circular_queue_alloc(queue_elements_num, frame_buf_size); 
      if (!queue) { 
       __android_log_print(ANDROID_LOG_ERROR, "SMPlayer", 
            "unable to allocate SPSC Circular Queue"); 
       opus_decoder_destroy(opus_dec); 
       return NULL; 
      } 

      /* initialize the play and start the playback */ 
      osl_player_init(queue, samplerate); 
      player_initialized = true; 
     } else { 
      int dec_samples = opus_decode(opus_dec, rcv_buf + 2, rcv_len - 2, 
             (int16_t *)dec_buf, sizeof(dec_buf), 0); 
      if (dec_samples <= 0) { 
       __android_log_print(ANDROID_LOG_ERROR, "SMPlayer", 
            "failed to decode the data"); 
       osl_player_terminate(); 
       spsc_circular_queue_free(queue); 
       opus_decoder_destroy(opus_dec); 
       exit(EXIT_FAILURE); 
      } 

      while (!spsc_circular_queue_push(queue, dec_buf) && !rcv_th_terminate) 
       usleep((useconds_t)(frame_length * 1000.0)); 

      if (!player_started) { 
       frames_in_queue++; 

       if (frames_in_queue == start_after) { 
        osl_player_jumpstart(queue); 
        player_started = true; 
       } 
      } 
     } 
    } 

    osl_player_terminate(); 

    if (empty_buf_cnt) 
     __android_log_print(ANDROID_LOG_DEBUG, "SMPlayer", 
          "Empty buffers played: %" PRIu64, empty_buf_cnt); 

    spsc_circular_queue_free(queue); 
    opus_decoder_destroy(opus_dec); 
} 

任意のアイデアを私のJNI呼び出すに

は、JNIのOpenSLのために、私はこのコードのスニペットを使うのか?!ありがとう、looot!

編集:Android 5.0.1では、Android 6.0.1では動作しません。なぜ ??

EDIT2:私の権限

<uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 
    <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> 

    <application 
     android:allowBackup="true" 

EDIT 3:後プットパーミッション、AndroidのマシュマロのRECORD AUDIO、変更なし、(サムスンS5:私は、私だけ

EDIT 4を聞き、記録しません)私は画面をロックすると、私のアプリはミュートのようです!

+0

あなたの許可を確認し、必要なものを追加するにはこれを見てください。 https://developer.android.com/training/permissions/requesting.html –

+0

RECORD_AUDIOは危険なアクセス許可です...実行時にmarshmallowで修正するために追加する必要があります –

+0

試しに追加しますが、私は考えません私は録音はしませんが、無線ネットワークを介してのみ聞くが、私はすぐにそれを試してみる)この許可が必要です – maathor

答えて

0

あなたの許可は6.0以上のアンドロイドバージョンで期限切れになると思いますので、あなたの許可が危険なアクセス許可にある場合はあなたの許可をチェックしてから、それを動的に与えてください。

+1

対処する許可がわかりません。私のマニフェストで? – maathor

関連する問題