2016-03-14 19 views
0

我想製作視頻拼貼,其中應該在一幀中顯示2個或更多視頻,然後將它們轉換爲一個視頻文件。 我嘗試了一些示例,但他們只是在每個視頻的末尾添加視頻,以製作長整合的視頻。 任何幫助,請我想幫助製作視頻拼貼,嘗試了一切但未成功

String FILE_PATH = "/storage/sdcard0/testing.mp4"; 
String FILE_PATH2 = "/storage/sdcard0/testing1.mp4"; 
String FILE_PATH3 = "/storage/sdcard0/testing2.mp4"; 
File file1 = new File(FILE_PATH); 
File file2 = new File(FILE_PATH2); 
File file3 = new File(FILE_PATH3); 

private ProgressDialog pDialog; 
ImageView img,img2,img3; 
MediaMetadataRetriever retriever2 = new MediaMetadataRetriever(); 
MediaMetadataRetriever retriever3 = new MediaMetadataRetriever(); 
ArrayList<Bitmap> bitmapArray1 = new ArrayList<Bitmap>(); 
ArrayList<Bitmap> bitmapArray2 = new ArrayList<Bitmap>(); 
ArrayList<Bitmap> bitmapArray3 = new ArrayList<Bitmap>(); 
File ScreenDIR = new File("/sdcard/Screens/"); 

//有對象創建的目錄結構,如果需要的話。

double id1=0,id2=0,id3=0; 



@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    ScreenDIR.mkdirs(); 

    img = (ImageView)findViewById(R.id.imageView); 
    img2 = (ImageView)findViewById(R.id.imageView2); 
    img3 = (ImageView)findViewById(R.id.imageView3); 

    new LoadAllProducts().execute(); 




} 

class LoadAllProducts extends AsyncTask<String, String, String> { 

    /** 
    * Before starting background thread Show Progress Dialog 
    * */ 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     pDialog = new ProgressDialog(MainActivity.this); 
     pDialog.setMessage("Extracting Frames. Please wait..."); 
     pDialog.setIndeterminate(false); 
     pDialog.setCancelable(false); 
     pDialog.show(); 
    } 

    /** 
    * getting All products from url 
    * */ 
    protected String doInBackground(String... args) { 
     if(file1.exists()){ 


      for (long i = 0; i < 5000; i += 1000/14) { // lenms - video length in milliseconds 

       MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 
       retriever.setDataSource(file1.toString()); 

       // Bitmap bitmap = retriever.getFrameAtTime((i*1000/14), MediaMetadataRetriever.OPTION_CLOSEST_SYNC); 

       saveBitmapToCahche(getResizedBitmap((retriever.getFrameAtTime((i*1000/14), MediaMetadataRetriever.OPTION_CLOSEST_SYNC)), 500) ,String.valueOf(id1)); 
       id1++; 
       //bitmapArray1.add(bitmap); 

       /* File file = new File(ScreenDIR, "sketchpad1" + id1 + ".png"); 
       FileOutputStream fOut = null; 
       try { 
        fOut = new FileOutputStream(file); 
       } catch (FileNotFoundException e) { 
        e.printStackTrace(); 
       } 

       //bitmap.compress(Bitmap.CompressFormat.PNG, 30, fOut); 

       try { 
        fOut.flush(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       try { 
        fOut.close(); 


       } catch (IOException e) { 
        e.printStackTrace(); 
       }*/ 
      } 

      } 
     /* if(file2.exists()){ 
      retriever2.setDataSource(file2.toString()); 
      for (long i = 0; i < 3000; i += 1000/24) { // lenms - video length in milliseconds 
       bitmap2 = retriever2.getFrameAtTime(i*1000/29, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); 
       //bitmapArray2.add(bitmap2); 

       File file = new File(ScreenDIR, "sketchpad2" + id2 + ".png"); 
       FileOutputStream fOut = null; 
       try { 
        fOut = new FileOutputStream(file); 
       } catch (FileNotFoundException e) { 
        e.printStackTrace(); 
       } 

       bitmap2.compress(Bitmap.CompressFormat.PNG, 85, fOut); 
       try { 
        fOut.flush(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       try { 
        fOut.close(); 
        id2++; 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 



     } 
     if(file3.exists()){ 
      retriever3.setDataSource(file3.toString()); 
      for (long i = 0; i < 3000; i += 1000/24) { // lenms - video length in milliseconds 
       bitmap3 = retriever3.getFrameAtTime(i*1000/29, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); 
       // bitmapArray3.add(bitmap3); 

       File file = new File(ScreenDIR, "sketchpad3" + id3 + ".png"); 
       FileOutputStream fOut = null; 
       try { 
        fOut = new FileOutputStream(file); 
       } catch (FileNotFoundException e) { 
        e.printStackTrace(); 
       } 

       bitmap3.compress(Bitmap.CompressFormat.PNG, 85, fOut); 
       try { 
        fOut.flush(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       try { 
        fOut.close(); 
        id3++; 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 

      }*/ 




     return null; 
    } 
    /** 
    * After completing background task Dismiss the progress dialog 
    * **/ 
    protected void onPostExecute(String file_url) { 
     // dismiss the dialog after getting all products 
     pDialog.dismiss(); 



     img.setImageBitmap(retrieveBitmapFromCache(String.valueOf(id2))); 
     id2 = 50; 

     img2.setImageBitmap(retrieveBitmapFromCache(String.valueOf(id2))); 
     id2 = 69; 

     img3.setImageBitmap(retrieveBitmapFromCache(String.valueOf(id2))); 


     // img2.setImageBitmap(bitmapArray2.get(0)); 
     // img3.setImageBitmap(bitmapArray3.get(0)); 

     } 




    } 


public void saveBitmapToCahche(Bitmap bb,String ID){ 

    Cache.getInstance().getLru().put(ID, bb); 


} 
public Bitmap retrieveBitmapFromCache(String ID) { 


    Bitmap bitmap = (Bitmap) Cache.getInstance().getLru().get(ID); 

    return bitmap; 

} 
public Bitmap getResizedBitmap(Bitmap image, int maxSize) { 
    int width = image.getWidth(); 
    int height = image.getHeight(); 

    float bitmapRatio = (float)width/(float) height; 
    if (bitmapRatio > 0) { 
     width = maxSize; 
     height = (int) (width/bitmapRatio); 
    } else { 
     height = maxSize; 
     width = (int) (height * bitmapRatio); 
    } 
    return Bitmap.createScaledBitmap(image, width, height, true); 
} 
} 

`

回答

0

創建視頻的每一幀的位圖一個新的框架是極其緩慢的,而不是存儲在友好的一切。除此之外,MediaMetadataRetriever會給你很多冗餘幀。當你完成爲兩個視頻創建位圖的時候,你將只有兩個視頻的4-5個不同的位圖。

要從視頻中提取每一幀,您必須在MediaExtractor中使用MediaCodec。

創建拼貼有點棘手。有一件事是H264編碼只支持特定的幀大小。當您並排添加兩個視頻時,它不一定適合支持的幀大小。

這就是說,我認爲它可能與從兩個視頻並排渲染幀到GLSurfaceView並將該表面共享給Mediacodec,該編碼將該幀編碼爲h264。我還沒有實現這一點,但我相信這是一種無需處理NDK的方法。

FFMPEG也爲此構建了功能。如果你對NDK感到滿意。

+0

這就是說,我認爲它可能與渲染幀並列兩個視頻到GLSurfaceView和共享該表面Mediacodec,這將幀編碼爲h264 你可以給任何例子或幫助這一行的答案 –

+0

我手邊沒有任何示例/內容。我會嘗試搜索一些東西,一旦我獲得免費。 – Ankit

+0

所以檢查這一點。 http://stackoverflow.com/questions/31340382/manipulate-a-custom-glsurfaceview-in-android 那裏的答案解釋了你想要創建什麼。另外還有鏈接到Grafika項目,它也有代碼示例。回答這個問題的Fadden也是Grafika的作者,曾經是谷歌Android團隊的成員。 – Ankit

0

分割視頻劃分爲幀,例如

MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 
File file1 = new File(directory, "file.mp4"); 
retriever.setDataSource(file1.toString()); 
for (long i = 0; i < lenms; i += 1000/fps) { // lenms - video length in milliseconds 
    Bitmap bitmap = retriever.getFrameAtTime(i*1000/fps, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); 
} 

,並從位圖

+0

你的意思是我應該從每個視頻中提取每幀,然後將這些幀編譯成一幀,當我將有很多組合幀,然後我將它們轉換成mp4視頻? –

+0

是的。也許會有不同的比特率。視頻#1 - 24 fps,視頻#2 - 30 fps。 –

+0

感謝您的幫助。我厭倦了它,它工作正常,但是當我把位圖放入arrayList,然後它不能超過8或10 bitmaps ..它最終崩潰,最終由於內存超出界限錯誤 –

相關問題