标签:des android com http blog style class div img code java
转载此处:http://www.apkbus.com/blog-86476-43829.html
上一篇文章进行了思路和16进制文件的分析。这篇该代码实现了。目前没有在真实手机上测试, android4.0之后的模拟器可以用模拟摄像头或者叫做webcam的【其实就是笔记本摄像头】。之后会在程序安装包data/data/edu.ustb.videoencoder/下面会有h264.3gp,sps【存放sps数据】、pps【存放pps数据】、media.xml【存放找到mdat的位置】,/sdcard/encoder.h264【这个文件就是编码后的h264文件】。
| 
       1 
      2 
      3 
      4 
      5 
      6 
      7 
      8 
      9 
      10 
      11 
      12 
      13 
      14 
      15 
      16 
      17 
      18 
      19 
      20 
      21 
      22 
      23 
      24 
      25 
      26 
      27 
      28 
      29 
      30  | 
    
      <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> | 
| 
       1 
      2 
      3 
      4 
      5 
      6 
      7 
      8 
      9 
      10 
      11 
      12 
      13 
      14 
      15 
      16 
      17 
      18 
      19 
      20 
      21 
      22 
      23 
      24 
      25 
      26 
      27 
      28 
      29 
      30 
      31 
      32 
      33 
      34 
      35 
      36 
      37 
      38 
      39 
      40 
      41 
      42 
      43 
      44 
      45 
      46 
      47 
      48 
      49 
      50 
      51 
      52 
      53 
      54 
      55 
      56 
      57 
      58 
      59 
      60 
      61 
      62 
      63 
      64 
      65 
      66 
      67 
      68 
      69 
      70 
      71 
      72 
      73 
      74 
      75 
      76 
      77 
      78 
      79 
      80 
      81 
      82 
      83 
      84 
      85 
      86 
      87 
      88 
      89 
      90 
      91 
      92 
      93 
      94 
      95 
      96 
      97 
      98 
      99 
      100 
      101 
      102 
      103 
      104 
      105 
      106 
      107 
      108 
      109 
      110 
      111 
      112 
      113 
      114 
      115 
      116 
      117 
      118 
      119 
      120 
      121 
      122 
      123 
      124 
      125 
      126 
      127 
      128 
      129 
      130 
      131 
      132 
      133 
      134 
      135 
      136 
      137 
      138 
      139 
      140 
      141 
      142 
      143 
      144 
      145 
      146 
      147 
      148 
      149 
      150 
      151 
      152 
      153 
      154 
      155 
      156 
      157 
      158 
      159 
      160 
      161 
      162 
      163 
      164 
      165 
      166 
      167 
      168 
      169 
      170 
      171 
      172 
      173 
      174 
      175 
      176 
      177 
      178 
      179 
      180 
      181 
      182 
      183 
      184 
      185 
      186 
      187 
      188 
      189 
      190 
      191 
      192 
      193 
      194 
      195 
      196 
      197 
      198 
      199 
      200 
      201 
      202 
      203 
      204 
      205 
      206 
      207 
      208 
      209 
      210 
      211 
      212 
      213 
      214 
      215 
      216 
      217 
      218 
      219 
      220 
      221 
      222 
      223 
      224 
      225 
      226 
      227 
      228 
      229 
      230 
      231 
      232 
      233 
      234 
      235 
      236 
      237 
      238 
      239 
      240 
      241 
      242 
      243 
      244 
      245 
      246 
      247 
      248 
      249 
      250 
      251 
      252 
      253 
      254 
      255 
      256 
      257 
      258 
      259 
      260 
      261 
      262 
      263 
      264 
      265 
      266 
      267 
      268 
      269 
      270 
      271 
      272 
      273 
      274 
      275 
      276 
      277 
      278 
      279 
      280 
      281 
      282 
      283 
      284 
      285 
      286 
      287 
      288 
      289 
      290 
      291 
      292 
      293 
      294 
      295 
      296 
      297 
      298 
      299 
      300 
      301 
      302 
      303 
      304 
      305 
      306 
      307 
      308 
      309 
      310 
      311 
      312 
      313 
      314 
      315 
      316 
      317 
      318 
      319 
      320 
      321 
      322 
      323 
      324 
      325 
      326 
      327 
      328 
      329 
      330 
      331 
      332 
      333 
      334 
      335 
      336 
      337 
      338 
      339 
      340 
      341 
      342 
      343 
      344 
      345 
      346 
      347 
      348 
      349 
      350 
      351 
      352 
      353 
      354 
      355 
      356 
      357 
      358 
      359 
      360 
      361 
      362 
      363 
      364 
      365 
      366 
      367 
      368 
      369 
      370 
      371 
      372 
      373 
      374 
      375 
      376 
      377 
      378 
      379 
      380 
      381 
      382 
      383 
      384 
      385 
      386 
      387 
      388 
      389 
      390 
      391 
      392 
      393 
      394 
      395 
      396 
      397 
      398 
      399 
      400 
      401 
      402 
      403 
      404 
      405 
      406 
      407 
      408 
      409 
      410 
      411 
      412 
      413 
      414 
      415 
      416 
      417 
      418 
      419 
      420 
      421 
      422 
      423 
      424 
      425 
      426 
      427 
      428 
      429 
      430 
      431 
      432  | 
    
      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 LocalSocket    LocalServerSocket 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 PPS                file_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;        }    }         //初始化MediaRecorder    private 
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;//20K    private 
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和PPS                findSPSAndPPS();                //找到后重新初始化MediaRecorder                initializeVideo();            }                                    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 sps                         file_test.write(head);            file_test.write(PPS);//write pps                         int 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 PPS    private 
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 mdat                break;            }        }        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 data                byte[] sps_3gp = new 
byte[2];//sps length                sps_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 length                SPS = new 
byte[sps_length];                System.arraycopy(data, sps_start, SPS, 0, sps_length);                //save sps                FileOutputStream 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 data                int 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 PPS                file_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;    }    @Override    protected 
void onPause() {        // TODO Auto-generated method stub        super.onPause();        if(mMediaRecorderRecording)        {            releaseMediaRecorder();                         try 
{                lss.close();                receiver.close();                sender.close();            } catch 
(IOException e) {                Log.e(TAG, e.toString());            }                         mMediaRecorderRecording = false;        }        finish();    }          } | 
android流媒体之硬编码【代码篇】,码迷,mamicode.com
标签:des android com http blog style class div img code java
原文地址:http://www.cnblogs.com/huningjun/p/3695802.html