文章【Android 的視頻編碼 H263 MP4V H264】的代碼實現

轉載地址:http://blog.csdn.net/zblue78/article/details/6083374


此篇文章所述代碼,我沒有能正常用socket發送視頻。我上上篇文章所講述的代碼,是我跑通並且能正常用socket存儲視頻文件的代碼。

CSDN代碼地址,能正常運行: http://download.csdn.net/detail/cooler126/5777745


最近很多同學問我SPS和PPS在那裏設置,其實這篇文章只是我 上篇文章的一個簡單實現 

 

具體情況情看看上一篇

 

http://blog.csdn.net/zblue78/archive/2010/12/15/6078040.aspx

 

 這裏只用HTC的G7做了H264的程序,諒解!

 

csdn的資源慢了 粘代碼算了

 

資源 http://download.csdn.net/source/2918751

 

 

 

歡迎大家經常訪問我的blog http://blog.csdn.net/zblue78/

共同探討,啥也不說的 直接上碼

AndroidManifest.xml

 

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="com.zjzhang"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">  
  7.         <activity android:name=".VideoCameraActivity"  
  8.                  android:screenOrientation="landscape"  
  9.                   android:label="@string/app_name">  
  10.             <intent-filter>  
  11.                 <action android:name="android.intent.action.MAIN" />  
  12.                 <category android:name="android.intent.category.LAUNCHER" />  
  13.             </intent-filter>  
  14.         </activity>  
  15.     </application>  
  16.    <uses-sdk android:minSdkVersion="3" />  
  17.     <uses-permission android:name="android.permission.INTERNET"/>  
  18.     <uses-permission android:name="android.permission.CAMERA"/>  
  19.     <uses-permission android:name="android.permission.RECORD_VIDEO"/>  
  20.     <uses-permission android:name="android.permission.RECORD_AUDIO"/>  
  21.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
  22. </manifest>   

main.xml

 

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7.     <SurfaceView   
  8.             android:id="@+id/surface_camera"  
  9.             android:layout_width="176px"  
  10.             android:layout_height="144px"  
  11.             android:layout_alignParentRight="true"  
  12.             android:layout_alignParentTop="true"  
  13.     />   
  14. </LinearLayout>  

 

  1. package com.zjzhang;  
  2. import java.io.DataInputStream;  
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.RandomAccessFile;  
  7. import android.app.Activity;  
  8. import android.content.Context;  
  9. import android.os.Bundle;  
  10. import android.graphics.PixelFormat;  
  11. import android.media.MediaRecorder;  
  12. import android.net.LocalServerSocket;  
  13. import android.net.LocalSocket;  
  14. import android.net.LocalSocketAddress;  
  15. import android.util.Log;  
  16. import android.view.SurfaceHolder;  
  17. import android.view.SurfaceView;  
  18. import android.view.View;  
  19. import android.view.Window;  
  20. import android.view.WindowManager;  
  21. public class VideoCameraActivity extends Activity implements  
  22.         SurfaceHolder.Callback, MediaRecorder.OnErrorListener,  
  23.         MediaRecorder.OnInfoListener {  
  24.     private static final int mVideoEncoder =MediaRecorder.VideoEncoder.H264;  
  25.     private static final String TAG = "VideoCamera";  
  26.     LocalSocket receiver, sender;  
  27.     LocalServerSocket lss;  
  28.     private MediaRecorder mMediaRecorder = null;  
  29.     boolean mMediaRecorderRecording = false;  
  30.     private SurfaceView mSurfaceView = null;  
  31.     private SurfaceHolder mSurfaceHolder = null;  
  32.     Thread t;  
  33.     Context mContext = this;  
  34.     RandomAccessFile raf = null;  
  35.     @Override  
  36.     public void onCreate(Bundle savedInstanceState) {  
  37.         super.onCreate(savedInstanceState);  
  38.         getWindow().setFormat(PixelFormat.TRANSLUCENT);  
  39.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  40.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  41.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  42.         setContentView(R.layout.main);  
  43.         mSurfaceView = (SurfaceView) this.findViewById(R.id.surface_camera);  
  44.         SurfaceHolder holder = mSurfaceView.getHolder();  
  45.         holder.addCallback(this);  
  46.         holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
  47.         mSurfaceView.setVisibility(View.VISIBLE);  
  48.         receiver = new LocalSocket();  
  49.         try {  
  50.             lss = new LocalServerSocket("VideoCamera");  
  51.             receiver.connect(new LocalSocketAddress("VideoCamera"));  
  52.             receiver.setReceiveBufferSize(500000);  
  53.             receiver.setSendBufferSize(500000);  
  54.             sender = lss.accept();  
  55.             sender.setReceiveBufferSize(500000);  
  56.             sender.setSendBufferSize(500000);  
  57.         } catch (IOException e) {  
  58.             finish();  
  59.             return;  
  60.         }  
  61.     }  
  62.     @Override  
  63.     public void onStart() {  
  64.         super.onStart();  
  65.     }  
  66.     @Override  
  67.     public void onResume() {  
  68.         super.onResume();  
  69.     }  
  70.     @Override  
  71.     public void onPause() {  
  72.         super.onPause();  
  73.         if (mMediaRecorderRecording) {  
  74.             stopVideoRecording();  
  75.             try {  
  76.                 lss.close();  
  77.                 receiver.close();  
  78.                 sender.close();  
  79.             } catch (IOException e) {  
  80.                 e.printStackTrace();  
  81.             }  
  82.         }  
  83.         finish();  
  84.     }  
  85.     private void stopVideoRecording() {  
  86.         Log.d(TAG, "stopVideoRecording");  
  87.         if (mMediaRecorderRecording || mMediaRecorder != null) {  
  88.             if (t != null)  
  89.                 t.interrupt();  
  90.             try {  
  91.                 raf.close();  
  92.             } catch (IOException e) {  
  93.                 // TODO Auto-generated catch block  
  94.                 e.printStackTrace();  
  95.             }  
  96.             releaseMediaRecorder();  
  97.         }  
  98.     }  
  99.     private void startVideoRecording() {  
  100.         Log.d(TAG, "startVideoRecording");  
  101.         (t = new Thread() {  
  102.             public void run() {  
  103.                 int frame_size = 1024;  
  104.                 byte[] buffer = new byte[1024 * 64];  
  105.                 int num, number = 0;  
  106.                 InputStream fis = null;  
  107.                 try {  
  108.                     fis = receiver.getInputStream();  
  109.                 } catch (IOException e1) {  
  110.                     return;  
  111.                 }  
  112.                 try {  
  113.                     Thread.currentThread().sleep(500);  
  114.                 } catch (InterruptedException e1) {  
  115.                     e1.printStackTrace();  
  116.                 }  
  117.                 number = 0;  
  118.                 releaseMediaRecorder();  
  119.                 //如果是H264或是MPEG_4_SP的就要在這裏找到相應的設置參數的流  
  120.                 //avcC box H264的設置參數  
  121.                 //esds box MPEG_4_SP 的設置參數  
  122.                 //其實 如果分辨率 等數值不變的話,這些參數是不會變化的,  
  123.                 //那麼我就只需要在第一次運行的時候確定就可以了  
  124.                 while (true) {  
  125.                     try {  
  126.                         num = fis.read(buffer, number, frame_size);  
  127.                         number += num;  
  128.                         if (num < frame_size) {  
  129.                             break;  
  130.                         }  
  131.                     } catch (IOException e) {  
  132.                         break;  
  133.                     }  
  134.                 }  
  135.                   
  136.                 initializeVideo();  
  137.                 number = 0;  
  138.                 // 重新啓動捕獲,以獲取視頻流  
  139.                 DataInputStream dis=new DataInputStream(fis);  
  140.                   
  141.                 //讀取最前面的32個自己的空頭  
  142.                 try {  
  143.                     dis.read(buffer,0,32);  
  144.                 } catch (IOException e1) {  
  145.                     // TODO Auto-generated catch block  
  146.                     e1.printStackTrace();  
  147.                 }  
  148.                   
  149.                   
  150.                 try {  
  151.                     File file = new File("/sdcard/stream.h264");  
  152.                     if (file.exists())  
  153.                         file.delete();  
  154.                     raf = new RandomAccessFile(file, "rw");  
  155.                 } catch (Exception ex) {  
  156.                     Log.v("System.out", ex.toString());  
  157.                 }                 
  158.                   
  159.                   
  160.                   
  161.                   
  162.                 //這些參數要對應我現在的視頻設置,如果想變化的話需要去重新確定,  
  163.                 //當然不知道是不是不同的機器是不是一樣,我這裏只有一個HTC G7做測試。  
  164.                 byte[] h264sps={0x67,0x42,0x00,0x0C,(byte0x96,0x54,0x0B,0x04,(byte0xA2};  
  165.                 byte[] h264pps={0x68,(byte0xCE,0x38,(byte0x80};  
  166.                 byte[] h264head={0,0,0,1};  
  167.                 try {  
  168.                     raf.write(h264head);  
  169.                     raf.write(h264sps);  
  170.                     raf.write(h264head);  
  171.                     raf.write(h264pps);  
  172.                 } catch (IOException e1) {  
  173.                     // TODO Auto-generated catch block  
  174.                     e1.printStackTrace();  
  175.                 }  
  176.                 while (true)  
  177.                 {  
  178.                     try {  
  179.                         //讀取每場的長度  
  180.                         int h264length=dis.readInt();  
  181.                         number =0;  
  182.                         raf.write(h264head);  
  183.                         while(number<h264length)  
  184.                         {  
  185.                             int lost=h264length-number;  
  186.                             num = fis.read(buffer,0,frame_size<lost?frame_size:lost);  
  187.                             Log.d(TAG,String.format("H264 %d,%d,%d", h264length,number,num));  
  188.                             number+=num;  
  189.                             raf.write(buffer, 0, num);  
  190.                         }  
  191.                     } catch (IOException e) {  
  192.                         break;  
  193.                     }  
  194.                 }  
  195.             }  
  196.         }).start();  
  197.     }  
  198.     private boolean initializeVideo() {  
  199.         if (mSurfaceHolder==null)  
  200.             return false;  
  201.         mMediaRecorderRecording = true;  
  202.         if (mMediaRecorder == null)  
  203.             mMediaRecorder = new MediaRecorder();  
  204.         else  
  205.             mMediaRecorder.reset();  
  206.         mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);  
  207.         mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
  208.         mMediaRecorder.setVideoFrameRate(20);  
  209.         mMediaRecorder.setVideoSize(352288);  
  210.         mMediaRecorder.setVideoEncoder(mVideoEncoder);  
  211.         mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());  
  212.         mMediaRecorder.setMaxDuration(0);  
  213.         mMediaRecorder.setMaxFileSize(0);  
  214.         mMediaRecorder.setOutputFile(sender.getFileDescriptor());  
  215.         try {  
  216.             mMediaRecorder.setOnInfoListener(this);  
  217.             mMediaRecorder.setOnErrorListener(this);  
  218.             mMediaRecorder.prepare();  
  219.             mMediaRecorder.start();  
  220.         } catch (IOException exception) {  
  221.             releaseMediaRecorder();  
  222.             finish();  
  223.             return false;  
  224.         }  
  225.         return true;  
  226.     }  
  227.     private void releaseMediaRecorder() {  
  228.         Log.v(TAG, "Releasing media recorder.");  
  229.         if (mMediaRecorder != null) {  
  230.             if (mMediaRecorderRecording) {  
  231.                 try {  
  232.                     mMediaRecorder.setOnErrorListener(null);  
  233.                     mMediaRecorder.setOnInfoListener(null);  
  234.                     mMediaRecorder.stop();  
  235.                 } catch (RuntimeException e) {  
  236.                     Log.e(TAG, "stop fail: " + e.getMessage());  
  237.                 }  
  238.                 mMediaRecorderRecording = false;  
  239.             }  
  240.             mMediaRecorder.reset();  
  241.             mMediaRecorder.release();  
  242.             mMediaRecorder = null;  
  243.         }  
  244.     }  
  245.     @Override  
  246.     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {  
  247.         Log.d(TAG, "surfaceChanged");  
  248.         mSurfaceHolder = holder;  
  249.         if (!mMediaRecorderRecording) {  
  250.             initializeVideo();  
  251.             startVideoRecording();  
  252.         }  
  253.     }  
  254.     @Override  
  255.     public void surfaceCreated(SurfaceHolder holder) {  
  256.         Log.d(TAG, "surfaceCreated");  
  257.         mSurfaceHolder = holder;  
  258.     }  
  259.     @Override  
  260.     public void surfaceDestroyed(SurfaceHolder holder) {  
  261.         Log.d(TAG, "surfaceDestroyed");  
  262.         mSurfaceHolder = null;  
  263.     }  
  264.     @Override  
  265.     public void onInfo(MediaRecorder mr, int what, int extra) {  
  266.         switch (what) {  
  267.         case MediaRecorder.MEDIA_RECORDER_INFO_UNKNOWN:  
  268.             Log.d(TAG, "MEDIA_RECORDER_INFO_UNKNOWN");  
  269.             break;  
  270.         case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:  
  271.             Log.d(TAG, "MEDIA_RECORDER_INFO_MAX_DURATION_REACHED");  
  272.             break;  
  273.         case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED:  
  274.             Log.d(TAG, "MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED");  
  275.             break;  
  276.         }  
  277.     }  
  278.     @Override  
  279.     public void onError(MediaRecorder mr, int what, int extra) {  
  280.         if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {  
  281.             Log.d(TAG, "MEDIA_RECORDER_ERROR_UNKNOWN");  
  282.             finish();  
  283.         }  
  284.     }  
  285. }  

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章