2016-12-15 22 views
6

我正在使用cordova 6.4.0cordova-plugin-media流式無線電臺在Android應用程序。不幸的是,有一種情況是應用程序沒有正確響應。我們假設用戶想要流式放大器,但是當流加載時,他想中止它(例如,因爲流被關閉,或者需要很長時間才能加載)。Cordova媒體插件 - 停止流式傳輸不工作 - 釋放()凍結設備

在這種情況下,我無法取消該過程!

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日誌仍在工作,但在這種情況下不顯示任何錯誤。只有POWER按鈕仍在工作(它鎖定和解鎖屏幕)。從這種擰緊狀態恢復的唯一方法是重新啓動設備。

我應該如何取消媒體流,如果它沒有播放,但呢?這是插件中的錯誤嗎?

附加是代碼片段,我用它來處理媒體流式邏輯。就像上面所描述的那樣......它基本上可以工作,但是如果你多次調用它,它會減慢甚至凍結設備。

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

No ionic,just cordova'6.4.0' –

+0

@MichaelB我覺得你必須先調用media.stop(),然後調用media.release()來釋放資源。請試試 – Gandhi

回答

3

我發現,這是不是一個科爾多瓦問題,而是一個8年歲(!)Android的錯誤,這是從來沒有固定的。在這裏看到:

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流保存在一個變量中。

如果cordova調用mediaPlayerStatusChange回調函數,我們通過media_objects循環並檢查其中一個「待處理」對象的狀態是否已經變爲「正在運行」。 - Cordova只是在沒有任何指控的情況下調用媒體狀態改變回調函數,媒體對象恰好改變了狀態。這是不幸的,所以我們必須檢查是否有一個懸而未決的「過時」對象開始播放。如果是這樣,我們可以停止並釋放它。 (如果對象是實際播放,停止和釋放就像預期的 - 只有當它的不打,它會導致崩潰)

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

該解決方案對我的作品,但我仍然有興趣在一個更美好,更清潔的方式處理科多瓦的多個媒體流。