您的位置:首页 > 移动开发 > Android开发

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

2012-05-24 15:24 513 查看
转载: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
欢迎大家经常访问我的blog http://blog.csdn.net/zblue78/
共同探讨,啥也不说的 直接上码

AndroidManifest.xml

[xhtml] view plaincopy

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.zjzhang"

android:versionCode="1"

android:versionName="1.0">

<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">

<activity android:name=".VideoCameraActivity"

android:screenOrientation="landscape"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

<uses-sdk android:minSdkVersion="3" />

<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"/>

</manifest>

main.xml

[xhtml] view plaincopy

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<SurfaceView

android:id="@+id/surface_camera"

android:layout_width="176px"

android:layout_height="144px"

android:layout_alignParentRight="true"

android:layout_alignParentTop="true"

/>

</LinearLayout>

[java] view plaincopy

package com.zjzhang;

import java.io.DataInputStream;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.RandomAccessFile;

import android.app.Activity;

import android.content.Context;

import android.os.Bundle;

import android.graphics.PixelFormat;

import android.media.MediaRecorder;

import android.net.LocalServerSocket;

import android.net.LocalSocket;

import android.net.LocalSocketAddress;

import android.util.Log;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.View;

import android.view.Window;

import android.view.WindowManager;

public class VideoCameraActivity extends Activity implements

SurfaceHolder.Callback, MediaRecorder.OnErrorListener,

MediaRecorder.OnInfoListener {

private static final int mVideoEncoder =MediaRecorder.VideoEncoder.H264;

private static final String TAG = "VideoCamera";

LocalSocket receiver, sender;

LocalServerSocket lss;

private MediaRecorder mMediaRecorder = null;

boolean mMediaRecorderRecording = false;

private SurfaceView mSurfaceView = null;

private SurfaceHolder mSurfaceHolder = null;

Thread t;

Context mContext = this;

RandomAccessFile raf = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

getWindow().setFormat(PixelFormat.TRANSLUCENT);

requestWindowFeature(Window.FEATURE_NO_TITLE);

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

WindowManager.LayoutParams.FLAG_FULLSCREEN);

setContentView(R.layout.main);

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);

receiver = new LocalSocket();

try {

lss = new LocalServerSocket("VideoCamera");

receiver.connect(new LocalSocketAddress("VideoCamera"));

receiver.setReceiveBufferSize(500000);

receiver.setSendBufferSize(500000);

sender = lss.accept();

sender.setReceiveBufferSize(500000);

sender.setSendBufferSize(500000);

} catch (IOException e) {

finish();

return;

}

}

@Override

public void onStart() {

super.onStart();

}

@Override

public void onResume() {

super.onResume();

}

@Override

public void onPause() {

super.onPause();

if (mMediaRecorderRecording) {

stopVideoRecording();

try {

lss.close();

receiver.close();

sender.close();

} catch (IOException e) {

e.printStackTrace();

}

}

finish();

}

private void stopVideoRecording() {

Log.d(TAG, "stopVideoRecording");

if (mMediaRecorderRecording || mMediaRecorder != null) {

if (t != null)

t.interrupt();

try {

raf.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

releaseMediaRecorder();

}

}

private void startVideoRecording() {

Log.d(TAG, "startVideoRecording");

(t = new Thread() {

public void run() {

int frame_size = 1024;

byte[] buffer = new byte[1024 * 64];

int num, number = 0;

InputStream fis = null;

try {

fis = receiver.getInputStream();

} catch (IOException e1) {

return;

}

try {

Thread.currentThread().sleep(500);

} catch (InterruptedException e1) {

e1.printStackTrace();

}

number = 0;

releaseMediaRecorder();

//如果是H264或是MPEG_4_SP的就要在这里找到相应的设置参数的流

//avcC box H264的设置参数

//esds box MPEG_4_SP 的设置参数

//其实 如果分辨率 等数值不变的话,这些参数是不会变化的,

//那么我就只需要在第一次运行的时候确定就可以了

while (true) {

try {

num = fis.read(buffer, number, frame_size);

number += num;

if (num < frame_size) {

break;

}

} catch (IOException e) {

break;

}

}

initializeVideo();

number = 0;

// 重新启动捕获,以获取视频流

DataInputStream dis=new DataInputStream(fis);

//读取最前面的32个自己的空头

try {

dis.read(buffer,0,32);

} catch (IOException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

try {

File file = new File("/sdcard/stream.h264");

if (file.exists())

file.delete();

raf = new RandomAccessFile(file, "rw");

} catch (Exception ex) {

Log.v("System.out", ex.toString());

}

//这些参数要对应我现在的视频设置,如果想变化的话需要去重新确定,

//当然不知道是不是不同的机器是不是一样,我这里只有一个HTC G7做测试。

byte[] h264sps={0x67,0x42,0x00,0x0C,(byte) 0x96,0x54,0x0B,0x04,(byte) 0xA2};

byte[] h264pps={0x68,(byte) 0xCE,0x38,(byte) 0x80};

byte[] h264head={0,0,0,1};

try {

raf.write(h264head);

raf.write(h264sps);

raf.write(h264head);

raf.write(h264pps);

} catch (IOException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

while (true)

{

try {

//读取每场的长度

int h264length=dis.readInt();

number =0;

raf.write(h264head);

while(number<h264length)

{

int lost=h264length-number;

num = fis.read(buffer,0,frame_size<lost?frame_size:lost);

Log.d(TAG,String.format("H264 %d,%d,%d", h264length,number,num));

number+=num;

raf.write(buffer, 0, num);

}

} catch (IOException e) {

break;

}

}

}

}).start();

}

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(20);

mMediaRecorder.setVideoSize(352, 288);

mMediaRecorder.setVideoEncoder(mVideoEncoder);

mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

mMediaRecorder.setMaxDuration(0);

mMediaRecorder.setMaxFileSize(0);

mMediaRecorder.setOutputFile(sender.getFileDescriptor());

try {

mMediaRecorder.setOnInfoListener(this);

mMediaRecorder.setOnErrorListener(this);

mMediaRecorder.prepare();

mMediaRecorder.start();

} catch (IOException exception) {

releaseMediaRecorder();

finish();

return false;

}

return true;

}

private void releaseMediaRecorder() {

Log.v(TAG, "Releasing media recorder.");

if (mMediaRecorder != null) {

if (mMediaRecorderRecording) {

try {

mMediaRecorder.setOnErrorListener(null);

mMediaRecorder.setOnInfoListener(null);

mMediaRecorder.stop();

} catch (RuntimeException e) {

Log.e(TAG, "stop fail: " + e.getMessage());

}

mMediaRecorderRecording = false;

}

mMediaRecorder.reset();

mMediaRecorder.release();

mMediaRecorder = null;

}

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

Log.d(TAG, "surfaceChanged");

mSurfaceHolder = holder;

if (!mMediaRecorderRecording) {

initializeVideo();

startVideoRecording();

}

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

Log.d(TAG, "surfaceCreated");

mSurfaceHolder = holder;

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

Log.d(TAG, "surfaceDestroyed");

mSurfaceHolder = null;

}

@Override

public void onInfo(MediaRecorder mr, int what, int extra) {

switch (what) {

case MediaRecorder.MEDIA_RECORDER_INFO_UNKNOWN:

Log.d(TAG, "MEDIA_RECORDER_INFO_UNKNOWN");

break;

case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:

Log.d(TAG, "MEDIA_RECORDER_INFO_MAX_DURATION_REACHED");

break;

case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED:

Log.d(TAG, "MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED");

break;

}

}

@Override

public void onError(MediaRecorder mr, int what, int extra) {

if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {

Log.d(TAG, "MEDIA_RECORDER_ERROR_UNKNOWN");

finish();

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: