android mediarecorder 录制音频并通过socket,存储到本地
来源:互联网 发布:c语言全排列函数 编辑:程序博客网 时间:2024/05/15 14:58
原文地址:http://www.apkbus.com/blog-86476-43829.html
废话不说直接贴代码,看不懂代码的同志可以参考:
http://blog.csdn.net/zblue78/article/details/6078040
http://blog.csdn.net/zblue78/article/details/6058147
这两篇讲的比较详细,不过他的代码我没有跑通。下面贴出我跑通的代码:
CSDN代码地址,能正常运行:http://download.csdn.net/detail/cooler126/5777745
上一篇文章进行了思路和16进制文件的分析。这篇该代码实现了。目前没有在真实手机上测试, android4.0之后的模拟器可以用模拟摄像头或者叫做webcam的【其实就是笔记本摄像头】。之后会在程序安装包data/data/edu.ustb.videoencoder/下面会有h264.3gp,sps【存放sps数据】、pps【存放pps数据】、media.xml【存放找到mdat的位置】,/sdcard/encoder.h264【这个文件就是编码后的h264文件】。
不多说,上源码。
[代码]:AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="edu.ustb.videoencoder" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.RECORD_VIDEO"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
[主程序代码]MainActivity.java:
package edu.ustb.videoencoder;import java.io.DataInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.RandomAccessFile;import android.media.MediaRecorder;import android.net.LocalServerSocket;import android.net.LocalSocket;import android.net.LocalSocketAddress;import android.os.Bundle;import android.app.Activity;import android.content.Context;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.util.Log;import android.view.Menu;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;import android.view.View;public class MainActivity extends Activity implements Callback, Runnable{private static final String TAG = "VideoCamera"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); InitSurfaceView(); InitMediaSharePreference(); } //初始化SurfaceView private SurfaceView mSurfaceView;private void InitSurfaceView() {mSurfaceView = (SurfaceView) this.findViewById(R.id.surface_camera);SurfaceHolder holder = mSurfaceView.getHolder();holder.addCallback(this);holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);mSurfaceView.setVisibility(View.VISIBLE);}//初始化,记录mdat开始位置的参数SharedPreferences sharedPreferences;private final String mediaShare = "media"; private void InitMediaSharePreference() {sharedPreferences = this.getSharedPreferences(mediaShare, MODE_PRIVATE);} private SurfaceHolder mSurfaceHolder; private boolean mMediaRecorderRecording = false; public void surfaceCreated(SurfaceHolder holder) {mSurfaceHolder = holder;}public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {mSurfaceHolder = holder;if(!mMediaRecorderRecording) {InitLocalSocket();getSPSAndPPS();initializeVideo();startVideoRecording();}}public void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stub}//初始化LocalServerSocket LocalSocketLocalServerSocket lss;LocalSocket receiver, sender;private void InitLocalSocket(){try {lss = new LocalServerSocket("H264");receiver = new LocalSocket();receiver.connect(new LocalSocketAddress("H264"));receiver.setReceiveBufferSize(500000);receiver.setSendBufferSize(50000);sender = lss.accept();sender.setReceiveBufferSize(500000);sender.setSendBufferSize(50000);} catch (IOException e) {Log.e(TAG, e.toString());this.finish();return;}}//得到序列参数集SPS和图像参数集PPS,如果已经存储在本地private void getSPSAndPPS(){StartMdatPlace = sharedPreferences.getInt(String.format("mdata_%d%d.mdat", videoWidth, videoHeight), -1);if(StartMdatPlace != -1) {byte[] temp = new byte[100];try {FileInputStream file_in = MainActivity.this.openFileInput(String.format("%d%d.sps", videoWidth,videoHeight));int index = 0;int read=0;while(true){read = file_in.read(temp,index,10);if(read==-1) break;else index += read;}Log.e(TAG, "sps length:"+index);SPS = new byte[index];System.arraycopy(temp, 0, SPS, 0, index); file_in.close();index =0;//read PPSfile_in = MainActivity.this.openFileInput(String.format("%d%d.pps", videoWidth,videoHeight));while(true){read = file_in.read(temp,index,10);if(read==-1) break;else index+=read;}Log.e(TAG, "pps length:"+index);PPS = new byte[index];System.arraycopy(temp, 0, PPS, 0, index);} catch (FileNotFoundException e) {//e.printStackTrace();Log.e(TAG, e.toString());} catch (IOException e) {//e.printStackTrace();Log.e(TAG, e.toString());}} else {SPS = null;PPS = null;}}//初始化MediaRecorderprivate MediaRecorder mMediaRecorder = null;private int videoWidth = 320;private int videoHeight = 240;private int videoRate = 10;private String fd = "data/data/edu.ustb.videoencoder/h264.3gp";private boolean initializeVideo(){if(mSurfaceHolder == null) {return false;}mMediaRecorderRecording = true;if(mMediaRecorder == null) {mMediaRecorder = new MediaRecorder();} else {mMediaRecorder.reset();}mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);mMediaRecorder.setVideoFrameRate(videoRate);mMediaRecorder.setVideoSize(videoWidth, videoHeight);mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());mMediaRecorder.setMaxDuration(0);mMediaRecorder.setMaxFileSize(0);if(SPS==null){mMediaRecorder.setOutputFile(fd);}else{mMediaRecorder.setOutputFile(sender.getFileDescriptor());}try {mMediaRecorder.prepare();mMediaRecorder.start();} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();releaseMediaRecorder();}return true;}//释放MediaRecorder资源private void releaseMediaRecorder(){if(mMediaRecorder != null) {if(mMediaRecorderRecording) {mMediaRecorder.stop();mMediaRecorderRecording = false;}mMediaRecorder.reset();mMediaRecorder.release();mMediaRecorder = null;}}//开始录像,启动线程private void startVideoRecording() {new Thread(this).start();}private final int MAXFRAMEBUFFER = 20480;//20Kprivate byte[] h264frame = new byte[MAXFRAMEBUFFER];private final byte[] head = new byte[]{0x00,0x00,0x00,0x01};private RandomAccessFile file_test;public void run() {try {if(SPS == null) {Log.e(TAG, "Rlease MediaRecorder and get SPS and PPS");Thread.sleep(1000);//释放MediaRecorder资源releaseMediaRecorder();//从已采集的视频数据中获取SPS和PPSfindSPSAndPPS();//找到后重新初始化MediaRecorderinitializeVideo();}DataInputStream dataInput = new DataInputStream(receiver.getInputStream());//先读取ftpy box and mdat box, 目的是skip ftpy and mdat data,(decisbe by phone)dataInput.read(h264frame, 0, StartMdatPlace);try {File file = new File("/sdcard/encoder.h264");if (file.exists())file.delete();file_test = new RandomAccessFile(file, "rw");} catch (Exception ex) {Log.v("System.out", ex.toString());}file_test.write(head);file_test.write(SPS);//write spsfile_test.write(head);file_test.write(PPS);//write ppsint h264length =0;while(mMediaRecorderRecording) {h264length = dataInput.readInt();Log.e(TAG, "h264 length :" + h264length);//int number=0 , num=0;//int frame_size = 1024;//file_test.write(head);//while(number<h264length)//{//int lost=h264length-number;//num = dataInput.read(h264frame,0,frame_size<lost?frame_size:lost);//Log.d(TAG,String.format("H264 %d,%d,%d", h264length,number,num));//number+=num;//file_test.write(h264frame, 0, num);//}ReadSize(h264length, dataInput);byte[] h264 = new byte[h264length];System.arraycopy(h264frame, 0, h264, 0, h264length);file_test.write(head);file_test.write(h264);//write selice} file_test.close();} catch (Exception e) {e.printStackTrace();}}private void ReadSize(int h264length,DataInputStream dataInput) throws IOException, InterruptedException{int read = 0;int temp = 0;while(read<h264length){temp= dataInput.read(h264frame, read, h264length-read);Log.e(TAG, String.format("h264frame %d,%d,%d", h264length,read,h264length-read));if(temp==-1){Log.e(TAG, "no data get wait for data coming.....");Thread.sleep(2000);continue;}read += temp;}}//从 fd文件中找到SPS And PPSprivate byte[] SPS;private byte[] PPS;private int StartMdatPlace = 0;private void findSPSAndPPS() throws Exception{File file = new File(fd);FileInputStream fileInput = new FileInputStream(file);int length = (int)file.length();byte[] data = new byte[length];fileInput.read(data);final byte[] mdat = new byte[]{0x6D,0x64,0x61,0x74};final byte[] avcc = new byte[]{0x61,0x76,0x63,0x43};for(int i=0 ; i<length; i++){if(data[i] == mdat[0] && data[i+1] == mdat[1] && data[i+2] == mdat[2] && data[i+3] == mdat[3]){StartMdatPlace = i+4;//find mdatbreak;}}Log.e(TAG, "StartMdatPlace:"+StartMdatPlace);//记录到xml文件里String mdatStr = String.format("mdata_%d%d.mdat",videoWidth,videoHeight);Editor editor = sharedPreferences.edit();editor.putInt(mdatStr, StartMdatPlace);editor.commit();for(int i=0 ; i<length; i++){if(data[i] == avcc[0] && data[i+1] == avcc[1] && data[i+2] == avcc[2] && data[i+3] == avcc[3]){int sps_start = i+3+7;//其中i+3指到avcc的c,再加7跳过6位AVCDecoderConfigurationRecord参数//sps length and sps databyte[] sps_3gp = new byte[2];//sps lengthsps_3gp[1] = data[sps_start];sps_3gp[0] = data[sps_start + 1];int sps_length = bytes2short(sps_3gp);Log.e(TAG, "sps_length :" + sps_length);sps_start += 2;//skip lengthSPS = new byte[sps_length];System.arraycopy(data, sps_start, SPS, 0, sps_length);//save spsFileOutputStream file_out = MainActivity.this.openFileOutput(String.format("%d%d.sps",videoWidth,videoHeight), Context.MODE_PRIVATE);file_out.write(SPS);file_out.close();//pps length and pps dataint pps_start = sps_start + sps_length + 1;byte[] pps_3gp =new byte[2];pps_3gp[1] = data[pps_start];pps_3gp[0] =data[pps_start+1];int pps_length = bytes2short(pps_3gp);Log.e(TAG, "PPS LENGTH:"+pps_length);pps_start+=2;PPS = new byte[pps_length];System.arraycopy(data, pps_start, PPS,0,pps_length);//Save PPSfile_out = MainActivity.this.openFileOutput(String.format("%d%d.pps",videoWidth,videoHeight),Context.MODE_PRIVATE);file_out.write(PPS);file_out.close();break;}}}//计算长度public short bytes2short(byte[] b) { short mask=0xff; short temp=0; short res=0; for(int i=0;i<2;i++) { res<<=8; temp=(short)(b[1-i]&mask); res|=temp; } return res; }@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; }@Overrideprotected void onPause() {// TODO Auto-generated method stubsuper.onPause();if(mMediaRecorderRecording){releaseMediaRecorder();try {lss.close();receiver.close();sender.close();} catch (IOException e) {Log.e(TAG, e.toString());}mMediaRecorderRecording = false;}finish();}}
- android mediarecorder 录制音频并通过socket,存储到本地
- Android MediaRecorder录制音频
- Android MediaRecorder录制音频
- android MediaRecorder录制音频
- Android播放器MediaPlayer与MediaRecorder:录制音频并播放
- Android之MediaRecorder录制音频
- Android:使用MediaRecorder录制音频
- MediaRecorder录制音频 保存到SD卡
- android MediaRecorder 录制音频、视频代码片段
- Android之多媒体--使用MediaRecorder录制音频
- Android多媒体之音频、视频录制MediaRecorder
- Android音频开发之使用MediaRecorder录制
- Android MediaRecorder与AudioRecord音频录制
- 使用MediaRecorder录制音频
- 使用MediaRecorder录制音频
- MediaRecorder录制音频
- MediaRecorder录制音频
- 使用MediaRecorder录制音频
- 数据结构(四.完)——O(nlogn)排序
- java中的多线程
- 内核抢占
- 解决MAC OS X 10.6.*无法安装软件的问题
- javascript数组操作大全,数组方法总汇
- android mediarecorder 录制音频并通过socket,存储到本地
- VS2008ReportViewer控件,在IE8下浏览出现文本框中插入的图表无法显示
- 底部菜单栏之Fragment的详细介绍和使用方法
- 430 F149 DS18B20数码管温度计设计
- 海量数据处理分析
- local unversioned, incoming add upon update
- PHP5.2 apache2.2 连接oracle9i 解决办法
- C#设置Cookies
- cocos2d-x 实现clash of clans多点聚焦缩放场景