2011-09-22 181 views
19

我正在開發Android應用程序,我正在使用Android SDK的MediaPlayer在我的應用程序中播放一些視頻。當我在我的應用程序中播放視頻時,大約有五分之一的時間,音頻播放時沒有視頻。這不是一個簡單的編碼錯誤,因爲大部分時間視頻播放完美。Android MediaPlayer - 有時即使播放音頻也沒有播放視頻

我認爲在我的代碼中的競爭條件導致了錯誤。但是,我添加了一些調試語句,並且在視頻不播放時似乎都可以正確設置所有內容。

我掃描了網頁,試圖找到解決方案,但沒有一個是足夠的(見下文)。

有沒有人遇到過這種類型的問題?如果是這樣,你做了什麼?

類似的問題:

MediaPlayer Video not played

android media player shows audio but no video

android video, hear sound but no video

一些細節:

  • 我在兩部手機上遇到過這個錯誤。在三星充電視頻播放80%的時間和20%的時間有音頻,但沒有視頻。在T-Mobile Comet上,情況更糟;視頻僅播放大約10%的時間。
  • 這不是一個文件的問題,我試過各種視頻文件和編解碼器,並得到相同的問題。
  • 這不是存儲介質的問題。我試過在存儲在內部存儲器和SD卡上時播放視頻,這兩者都沒有什麼不同。我甚至在播放之前嘗試讀取一些文件,希望系統能夠緩存它,但這似乎也沒有幫助。

更新:

我已經調試這一點,並通過logcat的期待。我發現,當視頻作品,類似如下出現在logcat中:

09-28 00:09:03.651: VERBOSE/PVPlayer(10875): setVideoSurface(0x65638) 

但是,當視頻不玩了,它看起來像有一個空項:

09-28 00:03:35.284: VERBOSE/PVPlayer(10875): setVideoSurface(0x0) 

更新2:

當視頻無法播放時,MediaPlayer.OnInfoListener函數的參數爲​​what==MEDIA_ERROR_UNKNOWN(0x1)extra==35。我查看了Android代碼庫,試圖確定未知錯誤35的含義。我遇到了pv_player_interface.h文件,這表明錯誤代碼35對應於一個叫做PVMFInfoTrackDisable的東西。我搜索了這個術語,這個術語將我帶到一個名爲的文件中。該文件給了我以下難以理解的解釋:

4.34。PVMFInfoTrackDisable

關於特定軌跡的通知是 禁用。這是一個每個軌道的基礎上。對於未壓縮的 音頻/視頻格式,在選擇內容可用軌道 的過程中,如果解碼器不支持該軌道,則發送一個 PVMFInfoTrackDisable事件。如有必要,該事件將爲每個曲目發送一次 。

我覺得我已經走了很長的路,但我沒有更接近找到答案...仍在調查。

+1

您是否每次播放相同的媒體內容或不同的媒體內容? – bluefalcon

+0

您是否在多個設備上測試過以確保它不是設備錯誤? – Cameron

+0

我已經回覆了你的評論。 – speedplane

回答

18

我在一個完全hackish的方式解決了這個問題,雖然。有兩個問題實際上是:

  1. 邪惡的信息35消息:我發現偶爾MediaPlayer.OnInfoListener將調用額外== 35。當發生這種情況時,你會被搞砸,視頻將無法正常播放。我不知道是什麼原因造成的。我發現的唯一解決方法是嘗試重新啓動視頻並重新執行整個prepareAsync過程。視頻播放通常是第二次。

  2. 未設置視頻大小:即使在MediaPlayer.OnPreparedListener獲取(或等價地prepare()返回)之後,視頻大小可能不會被設置。準備好返回後,視頻大小通常會設置幾個毫秒,但是一會兒它就處於模糊狀態。如果在設置視頻大小之前調用MediaPlayer.start(),則播放有時(但不總是)會失敗。有兩種可能的解決方案:(1)輪詢MediaPlayer.getVideoHeight()或getVideoWidth(),直到它們不爲零或(2)等到OnVideoSizeChangedListener被調用。只有在這兩個事件之一後,你應該調用start()。

有了這兩個修復程序,視頻播放更加一致。這些問題很可能與我的手機有關(三星手機和T-Mobile Comet),所以如果其他手機上存在不同但類似的問題,我不會感到驚訝。

+1

優秀,卓越,出色的分析和解決方法! –

+0

我在這個問題上掙扎了好幾天。 OnPrepareListener並不意味着完全準備就緒。我採用解決方案(1),它的工作原理。非常感謝! –

+0

不適用於我:-(。我沒有得到35錯誤,高度和寬度總是很好 – Nativ

-4

我的Desire HD上也有這個問題,大概有1到2次。我嘗試了很多東西,但錯誤總是在那裏。畢竟我選擇在我的設備上安裝自定義ROM。之後它完美運行,我再也沒有遇到這個問題。

我知道它不是你想要聽到的那種答案,但我沒有找到其他靈魂。

這裏你可以找到自定義光盤爲您的設備:XDA Developers

我希望我可以幫助你。

誠摯的問候和快樂的電影看

Safari瀏覽器=)

+0

謝謝,但我正在編寫一個應用程序,不僅僅是試圖在手機上播放視頻。我無法告訴我的用戶安裝新的ROMS。 – speedplane

1

我一直在研究這個bug 2個星期,並且我已經或多或少地理解了真正的問題。當然我在談論邪惡信息35信息。如果您遇到了這個奇怪的錯誤,現在您可以開心並拍攝像三星這樣的供應商:D ...

問題來了,因爲用戶無法看到表面視圖(tabhost或暫停喚醒功能中的活動,有時不在焦點中,有時不在眼前(可能))。

這是因爲當一些復位該視頻它運行正常,因爲它獲得焦點或也許另一個活動/對象是不重疊的。

當其中一些發生時,媒體播放器認爲您無法看到視頻或無法播放,並且會禁用視頻軌道,從而在聽音樂時聽到最糟糕的工作時間頭痛。

會看到下一個錯誤,好運氣。 :D

-5

根本的問題是: 之前surfaceCreated調用你開始視頻播放,當持有者沒有準備好MediaPlayer時,讓你只聽到聲音但看不到圖片!

正確的方法是:

+5

正確的方法是.. ? – asteri

+0

當我輸入代碼時,它提示我一個錯誤! – yichouangle

2

以下speedplane的建議,我想出了以下代碼。如果MediaPlayer.getVideoHeight()在onPrepared中返回0,那麼我會延遲1秒,然後重試。現在如果它不是第一次播放,它通常會在1秒後播放。我已經看到它需要幾次嘗試。

private void videoPlayer(String path){ 
     if (mMediaController == null) 
     { 
     mMediaController = new MediaController(this); 
     mVideoView.setMediaController(mMediaController); 
     } 
     if (!mMediaController.isShowing()) 
     mMediaController.show(); 

     getWindow().setFormat(PixelFormat.TRANSLUCENT); 
     mVideoView.setVideoPath(path); 
     mVideoView.requestFocus(); 
     mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
      @Override 
       public void onPrepared(final MediaPlayer mp) { 
       mVideoView.seekTo(mImageSeek); 
       if (mp.getVideoHeight() == 0) { 
        final Handler handler = new Handler(); 
        handler.postDelayed(new Runnable() { 
         @Override 
          public void run() { 
          mVideoView.stopPlayback(); 
          mMediaController = null; 
          videoPlayer(mImageFilepath); 
         } 
        }, 1000); 
       } else 
        mVideoView.start(); 
      } 
     }); 
    }