文章【Android 的视频编码 H263 MP4V H264】的代码实现

转载:http://blog.csdn.net/zblue78/article/details/6083374


最近很多同学问我SPS和PPS在那里设置,其实这篇文章只是我 上篇文章的一个简单实现

具体情况情看看上一篇

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

这里只用HTC的G7做了H264的程序,谅解!

csdn的资源慢了 粘代码算了

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

欢迎大家经常访问我的bloghttp://blog.csdn.net/zblue78/

共同探讨,啥也不说的 直接上码

AndroidManifest.xml

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

main.xml

[xhtml] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns: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>

[java] view plain copy
  1. packagecom.zjzhang;
  2. importjava.io.DataInputStream;
  3. importjava.io.File;
  4. importjava.io.IOException;
  5. importjava.io.InputStream;
  6. importjava.io.RandomAccessFile;
  7. importandroid.app.Activity;
  8. importandroid.content.Context;
  9. importandroid.os.Bundle;
  10. importandroid.graphics.PixelFormat;
  11. importandroid.media.MediaRecorder;
  12. importandroid.net.LocalServerSocket;
  13. importandroid.net.LocalSocket;
  14. importandroid.net.LocalSocketAddress;
  15. importandroid.util.Log;
  16. importandroid.view.SurfaceHolder;
  17. importandroid.view.SurfaceView;
  18. importandroid.view.View;
  19. importandroid.view.Window;
  20. importandroid.view.WindowManager;
  21. publicclassVideoCameraActivityextendsActivityimplements
  22. SurfaceHolder.Callback,MediaRecorder.OnErrorListener,
  23. MediaRecorder.OnInfoListener{
  24. privatestaticfinalintmVideoEncoder=MediaRecorder.VideoEncoder.H264;
  25. privatestaticfinalStringTAG="VideoCamera";
  26. LocalSocketreceiver,sender;
  27. LocalServerSocketlss;
  28. privateMediaRecordermMediaRecorder=null;
  29. booleanmMediaRecorderRecording=false;
  30. privateSurfaceViewmSurfaceView=null;
  31. privateSurfaceHoldermSurfaceHolder=null;
  32. Threadt;
  33. ContextmContext=this;
  34. RandomAccessFileraf=null;
  35. @Override
  36. publicvoidonCreate(BundlesavedInstanceState){
  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. SurfaceHolderholder=mSurfaceView.getHolder();
  45. holder.addCallback(this);
  46. holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  47. mSurfaceView.setVisibility(View.VISIBLE);
  48. receiver=newLocalSocket();
  49. try{
  50. lss=newLocalServerSocket("VideoCamera");
  51. receiver.connect(newLocalSocketAddress("VideoCamera"));
  52. receiver.setReceiveBufferSize(500000);
  53. receiver.setSendBufferSize(500000);
  54. sender=lss.accept();
  55. sender.setReceiveBufferSize(500000);
  56. sender.setSendBufferSize(500000);
  57. }catch(IOExceptione){
  58. finish();
  59. return;
  60. }
  61. }
  62. @Override
  63. publicvoidonStart(){
  64. super.onStart();
  65. }
  66. @Override
  67. publicvoidonResume(){
  68. super.onResume();
  69. }
  70. @Override
  71. publicvoidonPause(){
  72. super.onPause();
  73. if(mMediaRecorderRecording){
  74. stopVideoRecording();
  75. try{
  76. lss.close();
  77. receiver.close();
  78. sender.close();
  79. }catch(IOExceptione){
  80. e.printStackTrace();
  81. }
  82. }
  83. finish();
  84. }
  85. privatevoidstopVideoRecording(){
  86. Log.d(TAG,"stopVideoRecording");
  87. if(mMediaRecorderRecording||mMediaRecorder!=null){
  88. if(t!=null)
  89. t.interrupt();
  90. try{
  91. raf.close();
  92. }catch(IOExceptione){
  93. //TODOAuto-generatedcatchblock
  94. e.printStackTrace();
  95. }
  96. releaseMediaRecorder();
  97. }
  98. }
  99. privatevoidstartVideoRecording(){
  100. Log.d(TAG,"startVideoRecording");
  101. (t=newThread(){
  102. publicvoidrun(){
  103. intframe_size=1024;
  104. byte[]buffer=newbyte[1024*64];
  105. intnum,number=0;
  106. InputStreamfis=null;
  107. try{
  108. fis=receiver.getInputStream();
  109. }catch(IOExceptione1){
  110. return;
  111. }
  112. try{
  113. Thread.currentThread().sleep(500);
  114. }catch(InterruptedExceptione1){
  115. e1.printStackTrace();
  116. }
  117. number=0;
  118. releaseMediaRecorder();
  119. //如果是H264或是MPEG_4_SP的就要在这里找到相应的设置参数的流
  120. //avcCboxH264的设置参数
  121. //esdsboxMPEG_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(IOExceptione){
  132. break;
  133. }
  134. }
  135. initializeVideo();
  136. number=0;
  137. //重新启动捕获,以获取视频流
  138. DataInputStreamdis=newDataInputStream(fis);
  139. //读取最前面的32个自己的空头
  140. try{
  141. dis.read(buffer,0,32);
  142. }catch(IOExceptione1){
  143. //TODOAuto-generatedcatchblock
  144. e1.printStackTrace();
  145. }
  146. try{
  147. Filefile=newFile("/sdcard/stream.h264");
  148. if(file.exists())
  149. file.delete();
  150. raf=newRandomAccessFile(file,"rw");
  151. }catch(Exceptionex){
  152. Log.v("System.out",ex.toString());
  153. }
  154. //这些参数要对应我现在的视频设置,如果想变化的话需要去重新确定,
  155. //当然不知道是不是不同的机器是不是一样,我这里只有一个HTCG7做测试。
  156. byte[]h264sps={0x67,0x42,0x00,0x0C,(byte)0x96,0x54,0x0B,0x04,(byte)0xA2};
  157. byte[]h264pps={0x68,(byte)0xCE,0x38,(byte)0x80};
  158. byte[]h264head={0,0,0,1};
  159. try{
  160. raf.write(h264head);
  161. raf.write(h264sps);
  162. raf.write(h264head);
  163. raf.write(h264pps);
  164. }catch(IOExceptione1){
  165. //TODOAuto-generatedcatchblock
  166. e1.printStackTrace();
  167. }
  168. while(true)
  169. {
  170. try{
  171. //读取每场的长度
  172. inth264length=dis.readInt();
  173. number=0;
  174. raf.write(h264head);
  175. while(number<h264length)
  176. {
  177. intlost=h264length-number;
  178. num=fis.read(buffer,0,frame_size<lost?frame_size:lost);
  179. Log.d(TAG,String.format("H264%d,%d,%d",h264length,number,num));
  180. number+=num;
  181. raf.write(buffer,0,num);
  182. }
  183. }catch(IOExceptione){
  184. break;
  185. }
  186. }
  187. }
  188. }).start();
  189. }
  190. privatebooleaninitializeVideo(){
  191. if(mSurfaceHolder==null)
  192. returnfalse;
  193. mMediaRecorderRecording=true;
  194. if(mMediaRecorder==null)
  195. mMediaRecorder=newMediaRecorder();
  196. else
  197. mMediaRecorder.reset();
  198. mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
  199. mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  200. mMediaRecorder.setVideoFrameRate(20);
  201. mMediaRecorder.setVideoSize(352,288);
  202. mMediaRecorder.setVideoEncoder(mVideoEncoder);
  203. mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
  204. mMediaRecorder.setMaxDuration(0);
  205. mMediaRecorder.setMaxFileSize(0);
  206. mMediaRecorder.setOutputFile(sender.getFileDescriptor());
  207. try{
  208. mMediaRecorder.setOnInfoListener(this);
  209. mMediaRecorder.setOnErrorListener(this);
  210. mMediaRecorder.prepare();
  211. mMediaRecorder.start();
  212. }catch(IOExceptionexception){
  213. releaseMediaRecorder();
  214. finish();
  215. returnfalse;
  216. }
  217. returntrue;
  218. }
  219. privatevoidreleaseMediaRecorder(){
  220. Log.v(TAG,"Releasingmediarecorder.");
  221. if(mMediaRecorder!=null){
  222. if(mMediaRecorderRecording){
  223. try{
  224. mMediaRecorder.setOnErrorListener(null);
  225. mMediaRecorder.setOnInfoListener(null);
  226. mMediaRecorder.stop();
  227. }catch(RuntimeExceptione){
  228. Log.e(TAG,"stopfail:"+e.getMessage());
  229. }
  230. mMediaRecorderRecording=false;
  231. }
  232. mMediaRecorder.reset();
  233. mMediaRecorder.release();
  234. mMediaRecorder=null;
  235. }
  236. }
  237. @Override
  238. publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intw,inth){
  239. Log.d(TAG,"surfaceChanged");
  240. mSurfaceHolder=holder;
  241. if(!mMediaRecorderRecording){
  242. initializeVideo();
  243. startVideoRecording();
  244. }
  245. }
  246. @Override
  247. publicvoidsurfaceCreated(SurfaceHolderholder){
  248. Log.d(TAG,"surfaceCreated");
  249. mSurfaceHolder=holder;
  250. }
  251. @Override
  252. publicvoidsurfaceDestroyed(SurfaceHolderholder){
  253. Log.d(TAG,"surfaceDestroyed");
  254. mSurfaceHolder=null;
  255. }
  256. @Override
  257. publicvoidonInfo(MediaRecordermr,intwhat,intextra){
  258. switch(what){
  259. caseMediaRecorder.MEDIA_RECORDER_INFO_UNKNOWN:
  260. Log.d(TAG,"MEDIA_RECORDER_INFO_UNKNOWN");
  261. break;
  262. caseMediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:
  263. Log.d(TAG,"MEDIA_RECORDER_INFO_MAX_DURATION_REACHED");
  264. break;
  265. caseMediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED:
  266. Log.d(TAG,"MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED");
  267. break;
  268. }
  269. }
  270. @Override
  271. publicvoidonError(MediaRecordermr,intwhat,intextra){
  272. if(what==MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN){
  273. Log.d(TAG,"MEDIA_RECORDER_ERROR_UNKNOWN");
  274. finish();
  275. }
  276. }
  277. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值