2016-12-15 2 views
6

私はcordova 6.4.0cordova-plugin-mediaをAndroidアプリケーションのストリーミングラジオ局に使用しています。残念ながら、アプリケーションが適切に応答しない場合があります。Cordovaのメディアプラグイン - ストリーミングストリーミングが動作しない - release()デバイスがフリーズする

ストリームをロードしているときに、ストリームを停止したい(ストリームがダウンしている、またはロードに非常に時間がかかるなど)ために、ユーザーが無線通信をストリーミングしたいとします。

この場合、私はプロセスをキャンセルできません!

media = new Media("http://direct.franceinfo.fr/live/franceinfo-midfi.mp3?ID=f9fbk29m84", mediaPlayerSuccess, mediaPlayerFail, mediaPlayerStatus); 
media.play(); 

ストリームをバッファリングするプロセスをキャンセルしますが、できません。

media.pause(); 
media.stop(); 

は、ADBログにエラーメッセージをスローしており、mediaPlayer-onErrorコールバックを呼び出しています。

D/AudioPlayer(3362): AudioPlayer Error: pausePlaying() called during invalid state: 1 
... 
D/AudioPlayer(3362): AudioPlayer Error: stopPlaying() called during invalid state: 1 

media.release()コマンドは、ストリームのロードを停止します。しかし、ストリームを止めることなくストリームを解放するだけでは、大きな問題が発生します。

メディアオブジェクトにmedia.release()を呼び出すと、システムは非常に遅く反応し、数秒でハングします。しかし、これを頻繁に行うと、システムは完全にフリーダイヤルです。これは、リモートコントロールコマンドをそれ以上許可しないという意味です。 Adb-logはまだ動作していますが、この場合はエラーは表示されません。電源ボタンだけがまだ作動しています(画面のロックとロック解除)。このネジ止め状態から回復する唯一の方法は、デバイスを再起動することです。

メディアストリームが再生されていない場合、どのように取り消す必要がありますか?これはプラグインのバグですか?

添付ファイルは、メディアストリーミングロジックの処理に使用するコードスニペットです。上記のように...基本的には動作しますが、複数回呼び出すとデバイスが遅くなったり、デバイスがフリーズすることさえあります。

function radioControl(action, media_src){ 
    //media_src is a webradio-streamurl. 

    if(action == 'play') { 

    // Initial Play 
    if(media === null){ 
     mediaCreateObject(media_src); 
    } 

    // If we get PLAY but on antoher station 
    else if(media.src != media_src){ 
     mediaReleaseRessources(); 
     mediaCreateObject(media_src); 
    } 

    //interrupt_timer = false; 
    if(media === null){ 
     mediaCreateObject(media_src); 
    } 
    media.play(); 
    } 
    else if (action === 'pause') { 
    //If we get "pause", but it didn't even start yet 
    if(media._duration == -1){ 
     mediaReleaseRessources(); 
    } 
    else{ 
     media.pause(); 
    } 
    } 
} 

function mediaCreateObject(media_src){ 
    media = new Media(media_src, mediaPlayerSuccess, mediaPlayerFail, mediaPlayerStatus); 
} 

function mediaReleaseRessources(){ 
    media.release(); 
} 
+0

は、イオン1または2または他のいずれかですか? –

+0

イオンがありません、コードオフ '6.4.0' –

+0

@MichaelB私はあなたがmedia.stop()を最初に呼び出してから、リソースを解放するためにmedia.release()を呼び出してください。試してみてください – Gandhi

答えて

3

私は、これはコルドバの問題が、固定されなかった8歳(!)アンドロイド - バグ、ではないこと、が分かりました。ここを参照してください:

https://code.google.com/p/android/issues/detail?id=959

MediaPlayer "crash" (deadlocks the calling thread) when resetting or releasing an unused MediaPlayer

基本的には問題がある:あなたが「リリース」(まだ)をプレイしていないメディアオブジェクトしようとした場合、それは、呼び出し元のスレッドがデッドロックになります、それは私が質問で言及した凍結を引き起こす。残念ながら、彼らはこのバグを決して解決しませんでしたが、単にそれを「時代遅れ」とマークしました。 Android 5.1.1ではバグはまだ明らかです。おそらく彼らはそれ以降のバージョンでそれを修正しました。


私はこの問題のためにかなり醜い回避策を作っていますが、機能しています。基本的に私がやったのは: すべてのメディアオブジェクトをjavaScriptオブジェクトに保存します。ユーザーが再生中に停止した場合、そのオブジェクトを停止して削除することができます。しかし、再生していない場合、このメディアオブジェクトをこのjavaScriptオブジェクトに残します。media_objects = {}; また、現在active_mediaストリームを変数に保存します。

コードバスがmediaPlayerStatusChange -callbackを呼び出す場合は、media_objectsをループし、「保留中」オブジェクトのステータスが「実行中」に変更されているかどうかを確認します。 - Cordova justsは、メディアオブジェクトが状態を正確に変更したことを何の兆候なくメディア状態変更コールバックを呼び出します。これは残念なことです。保留中の「古い」オブジェクトの1つが再生を開始したかどうかを確認する必要があります。もしそうなら、私たちはそれをやめて解放することができます。

このソリューションは、私の作品
function mediaPlayerStatusChange(status){ 
    mediaReleaseRessources(); 
    // handle status change.... 
    // ...... 
} 

function mediaReleaseRessources(){ 

    for(var key in media_objects) { 
    // We can only stop-and release an object, if it is playing 
    // If an object started playing, the "_duration"-value is != -1 
    if(key !== active_media && media_objects[key]._duration != -1) { 
     media_objects[key].stop(); 
     media_objects[key].release(); 
     delete media_objects[key]; 
    } 
    } 
} 

、しかし私はまだ良いときれいな方法に興味があります - (それはプレイしていない場合にのみ、それがクラッシュの原因となるオブジェクトが実際に再生されている場合は、停止し、リリースが意図したように動作します)コードワで複数のメディアストリームを処理する

関連する問題