我的目標是獲取一個M4V視頻文件,將一段視頻解碼爲PNG幀,修改這些幀並對修剪過的視頻(也轉換爲M4V)進行重新編碼。將位圖幀渲染到Surface進行編碼
工作流程如下:[Input Video] -> Export Frames -> Modify Frames -> Encode Frames -> [Output Video]
。
對於解碼過程,我一直在參考bigflake的例子。使用ExtractMpegFramesTest示例代碼,我能夠從.m4v
文件生成Bitmap
幀,並將幀導出爲PNG文件。
現在我正在嘗試重新編碼過程,嘗試使用EncodeAndMuxTest示例創建另一組編碼類。
我遇到的問題是,示例代碼似乎在OpenGL中生成原始幀。我有一系列Bitmaps
,我想編碼/渲染到對象。幾乎與解碼過程所做的相反。
大部分示例代碼都很好,似乎我只需修改generateSurfaceFrame()
即可將Bitmap
轉換爲Surface
與OpenGL。
這裏是我迄今爲止代碼:我覺得我應該能夠使用STextureRender
從ExtractMpegFramesTest例子來實現類似的
// Member variables (see EncodeAndMuxTest example)
private MediaCodec encoder;
private CodeInputSurface inputSurface;
private MediaMuxer muxer;
private int trackIndex;
private boolean hasMuxerStarted;
private MediaCodec.BufferInfo bufferInfo;
// This is called for each frame to be rendered into the video file
private void encodeFrame(Bitmap bitmap)
{
int textureId = 0;
try
{
textureId = loadTexture(bitmap);
// render the texture here?
}
finally
{
unloadTexture(textureId);
}
}
// Loads a texture into OpenGL
private int loadTexture(Bitmap bitmap)
{
final int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
int textureWidth = bitmap.getWidth();
int textureHeight = bitmap.getHeight();
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
return textures[0];
}
// Unloads a texture from OpenGL
private void unloadTexture(int textureId)
{
final int[] textures = new int[1];
textures[0] = textureId;
GLES20.glDeleteTextures(1, textures, 0);
}
,但它只是不點擊我。
另一件事是性能,我真的想要獲得高效的編碼。我將編碼90-450幀視頻(3-15秒@ 30fps),所以這應該只需要幾秒鐘。
您可以使用glTexImage()將位圖像素轉換爲GLES紋理,然後渲染紋理......這似乎是迄今爲止所做的。什麼不工作? Grafika中的一些代碼(https://github.com/google/grafika)可能有用。你正在進行什麼樣的修改?如果它很簡單,您可以使用GLES片段着色器進行處理,速度會更快(請參閱例如Grafika中的「顯示+捕獲」活動)。 – fadden
Woo @fadden,感謝您的評論!我正在執行的操作是修剪(從電影中選擇片段),縮放/平移(縮放+變換),調整幀大小以添加信箱(用於文本)以及在信箱區域中渲染文本。這些步驟中的每一個都需要用戶交互,例如捏縮放,拖動平移以及在相應的頂部/底部區域輸入文本。我使用'Canvas' /'Paint' /'Bitmap'對象完成所有工作,但着色器會很整齊。我對OpenGL有一個基本的瞭解,但着色器語言對我來說是新的。 – Erik
另外,我想這不像我在做什麼時有心理障礙那樣工作。在理論上,我應該能夠渲染它來繪製一個'GL_TRIANGLE_STRIP'四元組,類似於'ExtractMpegFramesTest示例中'STextureRender'的功能。我確實看過Grafika示例代碼,但我不確定在哪裏尋找示例,我會稍後再看看,看看我能想出什麼。 – Erik