2014-01-14 101 views
3

我想在我的Android設備上播放(渲染到表面)兩個或更多個連續的mp4視頻序列(每個都存儲在設備上的單獨文件中,可能不會在啓動時顯示)光滑的(沒有攤位,閃爍等)方式。所以,觀衆可能會得到僅觀看一個連續視頻的印象。在第一步中,僅用於Nexus 7平板電腦就足夠了。 對於只顯示一個視頻,我一直在使用MediaCodec API,與http://dpsm.wordpress.com/2012/07/28/android-mediacodec-decoded/類似,它工作正常。通過在第一個序列完成之後僅創建(並配置)第二個解碼器(第一個序列的解碼器.stop解碼器。發行被稱爲),可以看到混合。爲了在兩個不同的視頻序列之間平滑淡化,我正在考慮在第一個播放過程中第二個視頻已經通過解碼器配置(格式,表面,空值,0)初始化了一個功能。此外,第一幀還通過decoder.queueInputBuffer排隊。 但這樣做的結果是出現以下錯誤:在Android上連續播放mp4視頻序列

01-13 16:20:37.182: E/BufferQueue(183): [SurfaceView] connect: already connected (cur=3, req=3) 
01-13 16:20:37.182: E/MediaCodec(9148): native_window_api_connect returned an error: Invalid argument (-22) 
01-13 16:20:37.182: E/Decoder Init(9148): Exception decoder.configure: java.lang.IllegalStateException 

在我看來,一個表面只能由一個解碼器同時使用。那麼,有沒有其他的可能性呢?也許使用OpenGL?

最好, Alex。

回答

0

瘋狂的想法。嘗試margin the two videos to one。他們都在你的設備上,所以它不應該花很長時間。你可以自己實現淡入淡出效果。

+0

這絕對是一個有前途的方法,但可能並非所有的視頻序列已經存儲在我的設備上,當第一個播放開始時,我必須同時下載它們。因此,「連接」不適合我。 –

+0

@ A.Wolf流式傳輸比如何? –

+0

當然,它「感覺」類似於流式傳輸,但我們沒有連續的幀流。每個視頻序列都是幀的組合,比如約2秒的視頻。 –

1

您使用MediaCodec的多個實例描述的內容可以工作,但一次只能有一個「製作者」連接到Surface。您需要先拆下第一張,然後再繼續第二張,我不確定您有多接近時間。

你可以做的是解碼爲SurfaceTexture,然後在SurfaceView上繪製(使用,如你所想,OpenGL)。

您可以在ExtractMpegFramesTest示例中看到將MP4文件渲染到SurfaceTexture的示例。從那裏你只需要將紋理渲染到你的表面(SurfaceViewTextureView?),使用類似中的STextureRender類。

Grafika還有一些其他示例,儘管視頻播放器更接近您已有的內容(解碼器輸出爲TextureView)。順便說一句,你需要弄清楚在電影N的最後一幀和電影N + 1的第一幀之間放置了多少延遲。如果錄製是以固定幀速率拍攝的,則很容易,但有些來源(例如screenrecord)不以這種方式錄製。

更新:如果你能保證你的影片剪輯具有相同的特性(大小,編碼類型 - 基本上一切都在MediaFormat),還有一個更簡單的方法。當你碰到流結束時,你可以用flush()解碼器,然後開始在下一個文件中輸入數據。我用它來循環Grafika視頻播放器中的視頻(請參閱MoviePlayer#doExtract())。

+0

感謝您的示例(ExtractMpegFramesTest)對SurfaceTexture解碼解出來了!現在我面臨將紋理渲染到表面的問題。就我所知,CameraToMpegTest也在不顯示的情況下存儲視頻,對吧?我對SurfaceView以及TextureView都很滿意,但根據http://developer.android.com/training/graphics/opengl/environment.html,選擇TextureView可能會更容易。 Ps .:是的,可以保證影片剪輯具有相同的特徵和固定的幀速率。 –

+0

bigflake樣本不顯示任何內容。 ExtractMpegFramesTest創建一個SurfaceTexture,並將MediaCodec輸出指向它。要在TextureView上顯示輸出,您需要更改代碼,以便使用來自'TextureView#getSurfaceTexture()'的SurfaceTexture。然後TextureView類將負責鎖定緩衝區並將其渲染到屏幕上。 (如果您使用SurfaceView,則必須自己進行渲染。) – fadden

+0

我根據您的建議進行了一些更改;我創建了一個TextureView,並通過'mTextureView.setSurfaceTextureListener(this)'設置了一個監聽器。我將SurfaceTexture轉發到CodecOutputSurface並使用它,而不是創建一個新的。但是,當我嘗試通過mSurfaceTexture.attachToGLContext(mTextureRender.getTextureId())將它附加到GL上下文時,出現以下錯誤:「E/GLConsumer:[unnamed-11969-0] attachToContext:GLConsumer已附加到一個上下文「。是否有必要附加它?如何從這裏開始? –