Android 实时视频压缩传输(720P)

Server

package com.example.ict.compress;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;

public class MainActivity extends Activity
{
    private Camera mCamera = null;
    private SurfaceHolder holder = null;

    private Button button1,button2;


    private int width = 1280;
    private int height = 720;
    ServerSocket server = null;
    Socket socket = null;
    private static final int PORT = 5555;
    DataOutputStream out = null;
    private byte []rgb_data = new byte[width*height*4];
    ByteArrayOutputStream baos = null;
    Bitmap VideoBit = null;
    private ByteBuffer byteBuffer = null;
    ImageView imageView = null;
    private int number = 0;

    class Callback implements Camera.PreviewCallback
    {
        @Override
        public void onPreviewFrame(byte[] frame, Camera camera)
        {
            decodeYUV420SP(rgb_data,frame,width,height);
            VideoBit = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
            byteBuffer = ByteBuffer.wrap(rgb_data);
            byteBuffer.position(0);
            VideoBit.copyPixelsFromBuffer(byteBuffer);
            Matrix matrix = new Matrix();
            matrix.postRotate(90);
            baos = new ByteArrayOutputStream();
            VideoBit.compress(Bitmap.CompressFormat.JPEG,20,baos);
            byte []bytes = baos.toByteArray();


            //    imageView.setImageBitmap(Bitmap.createBitmap(BitmapFactory.decodeByteArray(bytes,0,bytes.length),0,0,width,height,matrix,true));

            try{
                number = bytes.length;
                out.writeInt(number);
                out.flush();
                out.write(bytes);
                out.flush();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SurfaceView mSurfaceView = (SurfaceView) this.findViewById(R.id.camera_preview);
        button1 = (Button) findViewById(R.id.b1);
        button2 = (Button) findViewById(R.id.b2);
        holder = mSurfaceView.getHolder();
        imageView = (ImageView)findViewById(R.id.imageView);
        new MyThread().start();
        button1.setOnClickListener(new Button.OnClickListener(){

            @Override
            public void onClick(View v) {

                if(mCamera == null)
                {
                    mCamera = Camera.open();
                    Camera.Parameters p = mCamera.getParameters();
                    p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
                    p.setPreviewSize(width,height);
                    p.setPreviewFrameRate(15);    //设置帧率
                    mCamera.setParameters(p);
                    mCamera.setDisplayOrientation(90);
                    try
                    {
                        mCamera.setPreviewDisplay(holder);
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                    mCamera.startPreview();

                    Callback a = new Callback();
                    mCamera.setPreviewCallback(a);
                }
            }
        });
        button2.setOnClickListener(new Button.OnClickListener(){

            @Override
            public void onClick(View v) {
                finish();
            }

        });
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void finalize()
    {
        try
        {
            super.finalize();
        }
        catch (Throwable e)
        {
            e.printStackTrace();
        }
    }

    public class MyThread extends Thread{
        public void run(){
            try{
                server = new ServerSocket(PORT);
                socket = server.accept();
                out = new DataOutputStream(socket.getOutputStream());
            }catch (IOException e){
                e.printStackTrace();
            }

        }
    }

    static public void decodeYUV420SP(byte[] rgb, byte[] yuv420sp, int width, int height) {
        final int frameSize = width * height;

        for (int j = 0, yp = 0; j < height; j++) {
            int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
            for (int i = 0; i < width; i++, yp++) {
                int y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0) y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }

                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);

                if (r < 0) r = 0; else if (r > 262143) r = 262143;
                if (g < 0) g = 0; else if (g > 262143) g = 262143;
                if (b < 0) b = 0; else if (b > 262143) b = 262143;

                rgb[yp*4] = (byte)(r >>10);
                rgb[yp*4+1] = (byte)(g >>10);
                rgb[yp*4+2] = (byte)(b >> 10);
                rgb[yp*4+3] = (byte)255;
            }
        }
    }

}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="50px"
        android:text="图像采集测试"
        android:gravity="center"
        />

    <SurfaceView
        android:id="@+id/camera_preview"
        android:layout_width="720px"
        android:layout_height="1280px"
        >
    </SurfaceView>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <Button
            android:id="@+id/b1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30px"
            android:text="采集"
            android:gravity="center"
            />

        <Button
            android:id="@+id/b2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30px"
            android:text="退出"
            android:gravity="center"
            />

    </LinearLayout>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@mipmap/ic_launcher"
        android:id="@+id/imageView" />

</LinearLayout>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ict.compress">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.CAMERA"/>

</manifest>

Client

package com.example.ict.video_frame_client;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.ByteBuffer;

public class MainActivity extends AppCompatActivity {

    private static final String HOST = "192.168.43.1";
    private static final int PORT = 5555;
    private static final int REFRESH = 0x000001;
    Socket socket = null;
    DataOutputStream out = null;
    DataInputStream in = null;
    Handler mHandler = null;
    private static final int width = 1280;
    private static final int height = 720;
    //  int size = width*height*3/2;
    int size  = 0;
    //   byte r_data[] = new byte[size];
    byte r_data[] = null;
    private byte rgb_data[] = new byte[width*height*4];
    private Bitmap VideoBit = null;
    private ByteBuffer byteBuffer = null;
    ImageView imageView = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);   //设置窗口无标题显示
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        imageView = (ImageView)findViewById(R.id.imageView);


        new MyThread().start();
        mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg){
                if(msg.what == REFRESH){
                    Matrix matrix = new Matrix();
                    matrix.postRotate(90);
                    imageView.setImageBitmap(Bitmap.createBitmap(BitmapFactory.decodeByteArray(r_data,0,r_data.length),0,0,width,height,matrix,true));

                  /*  decodeYUV420SP(rgb_data,r_data,width,height);
                    VideoBit = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
                    byteBuffer = ByteBuffer.wrap(rgb_data);
                    byteBuffer.position(0);
                    VideoBit.copyPixelsFromBuffer(byteBuffer);
                    Matrix matrix = new Matrix();
                    matrix.postRotate(90);
                    imageView.setImageBitmap(Bitmap.createBitmap(VideoBit, 0, 0, width, height, matrix, true));*/
                }
            }
        };

    }



    public class MyThread extends Thread{
        public void run(){
            try {
                socket = new Socket(HOST,PORT);
                in = new DataInputStream(socket.getInputStream());
                out = new DataOutputStream(socket.getOutputStream());
                //   out.writeBytes("Hello Server!");
            }catch (IOException e){
                e.printStackTrace();
            }
            while(!Thread.currentThread().isInterrupted()){
                Message msg = new Message();
                msg.what = REFRESH;
                int len = 0;
                try{
                    size = in.readInt();
                    r_data = new byte[size];
                    while(len<size)
                        len += in.read(r_data,len,size-len);
                }catch (IOException e){
                    e.printStackTrace();
                }

                mHandler.sendMessage(msg);
                try{
                    Thread.sleep(50);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }


    static public void decodeYUV420SP(byte[] rgb, byte[] yuv420sp, int width, int height) {
        final int frameSize = width * height;

        for (int j = 0, yp = 0; j < height; j++) {
            int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
            for (int i = 0; i < width; i++, yp++) {
                int y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0) y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }

                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);

                if (r < 0) r = 0; else if (r > 262143) r = 262143;
                if (g < 0) g = 0; else if (g > 262143) g = 262143;
                if (b < 0) b = 0; else if (b > 262143) b = 262143;

                rgb[yp*4] = (byte)(r >>10);
                rgb[yp*4+1] = (byte)(g >>10);
                rgb[yp*4+2] = (byte)(b >> 10);
                rgb[yp*4+3] = (byte)255;
            }
        }
    }


}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.ict.video_frame_client.MainActivity">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:srcCompat="@mipmap/ic_launcher"
        android:id="@+id/imageView" />

</LinearLayout>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ict.video_frame_client">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>

</manifest>


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值