在Android中使用Http实时视频流(录制和上传)

时间:2013-03-26 14:36:20

标签: android video-streaming android-camera http-live-streaming live-streaming

在我的应用程序中,我需要从设备录制视频并同时将其发布到服务器(每5秒钟)。为此我使用Http服务(我不想在这里使用RTSP)。我能够录制并同时发布它。

但是服务器端的文件无法播放(即使在VLC中也是如此)。两个文件的大小以字节为单位(服务器文件和设备文件)。为了测试目的,找出问题是在服务器或我的结束,我已经评论服务器发布代码和写入数据到SD卡中的另一个文件(同时每5秒录制)但该文件也相同的大小,无法播放在设备或VLC中。

package com.techgene.instantrecorder;

import java.io.File;
import java.io.IOException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnInfoListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.Toast;
import android.widget.VideoView;

import com.techgene.instantrecorder.utility.Util;

public class SafeVideoRecorder extends Activity implements SurfaceHolder.Callback
{
    public static final String EXTRA_USE_FRONT_FACING_CAMERA ="frontcamera";
    private static final String ROOT_DIR = Environment.getExternalStorageDirectory().toString() + "/InstantRecorder";

    private static final int DUAL_MODE = 1;
    private static final int MONO_MODE = 2;
    private int currentMode;

    private static final String TAG = "VideoRecorder";

    public static Boolean mRecording = false;
    private Boolean mUseFrontFacingCamera = false, isFromCall = false;
    private VideoView mVideoView = null;
    private MediaRecorder mVideoRecorder = null;
    private Camera mCamera;
    private String uniqueOutFile;
    private ProgressDialog progress;
    private Button btnStop, btnStartRecord, btnDual, btnMono;

    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_video_recorder);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        mVideoView = (VideoView) this.findViewById(R.id.videoView);

        btnStop = (Button) findViewById(R.id.btnStop);
        btnStop.setVisibility(View.GONE);
        btnStop.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v) 
            {
                try
                {
                    stopRecording();

                    if(progress != null && progress.isShowing())
                        progress.dismiss();

                    progress = ProgressDialog.show(SafeVideoRecorder.this, "", "Uploading...");

                    new Thread(new Runnable()
                    {
                        @Override
                        public void run() 
                        {
//                          Util util = new Util();
//                          final int respCode = util.upLoad2Server(uniqueOutFile);
//                          
//                          if(currentMode == MONO_MODE)
//                          {
//                              File file = new File(uniqueOutFile);
//                              if(file.exists())
//                                  file.delete();
//                          }

                            runOnUiThread(new Runnable()
                            {
                                @Override
                                public void run() 
                                {
                                    if(progress != null && progress.isShowing())
                                        progress.dismiss();

//                                  if(respCode == 200)
//                                  {
//                                      Toast.makeText(SafeVideoRecorder.this, "Successfully uploaded to server", Toast.LENGTH_SHORT).show();
//                                  }
//                                  else
//                                  {
//                                      Toast.makeText(SafeVideoRecorder.this, "Unable to upload server", Toast.LENGTH_SHORT).show();
//                                  }

                                    try {
                                        configureCameraRecorder(mVideoView.getHolder());
                                    } catch (Exception e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                    }

                                    btnStop.setVisibility(View.GONE);
                                    btnStartRecord.setVisibility(View.VISIBLE);

                                    btnDual.setVisibility(View.GONE);
                                    btnMono.setVisibility(View.GONE);
                                }
                            });
                        }
                    }).start();
                } 
                catch (Exception e) 
                {
                    Log.e(TAG, e.toString());
                    e.printStackTrace();
                }
            }
        });

        btnStartRecord = (Button) findViewById(R.id.btnStartRecord);
        btnStartRecord.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v) 
            {
                btnDual.setVisibility(View.VISIBLE);
                btnMono.setVisibility(View.VISIBLE);

                btnStop.setVisibility(View.GONE);
                btnStartRecord.setVisibility(View.GONE);

                startRecord();
            }
        });

        btnDual = (Button) findViewById(R.id.btnDual);
        btnDual.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v) 
            {
                currentMode = DUAL_MODE;
                isFromCall = true;
                Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+"9703033575"));
                startActivityForResult(intent, 1010);

                btnDual.setVisibility(View.GONE);
                btnMono.setVisibility(View.GONE);
                btnStartRecord.setVisibility(View.GONE);

                btnStop.setVisibility(View.VISIBLE);
            }
        });

        btnMono = (Button) findViewById(R.id.btnMono);
        btnMono.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v) 
            {
                currentMode = MONO_MODE;

                btnDual.setVisibility(View.GONE);
                btnMono.setVisibility(View.GONE);
                btnStartRecord.setVisibility(View.GONE);

                btnStop.setVisibility(View.VISIBLE);
            }
        });

        //mUseFrontFacingCamera = getIntent().getExtras().getBoolean(EXTRA_USE_FRONT_FACING_CAMERA, false);

        if(mUseFrontFacingCamera)
        {
            // If caller wants to use front facing camera, then make sure the device has one...
            // Hard coded to only open front facing camera on Xoom (model MZ604)
            // For more universal solution try: 
            // http://stackoverflow.com/questions/2779002/how-to-open-front-camera-on-android-platform
            String deviceModel = android.os.Build.MODEL;
            if (deviceModel.contains("MZ604"))
            {
                mUseFrontFacingCamera = true;
            } 
            else 
            {
                Toast.makeText(getApplicationContext(), "The App isn't designed to use this Android's front facing camera.\n " +
                                                        "The device model is : " + deviceModel, Toast.LENGTH_LONG).show();
                mUseFrontFacingCamera = false;
            }
        }

        final SurfaceHolder holder = mVideoView.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @SuppressLint("NewApi") @Override
    public void surfaceCreated(SurfaceHolder holder) 
    {
        Log.e(TAG, "surfaceCreated()");

        try
        {
            if(!isFromCall)
            {
                Log.e(TAG, "configureCameraRecorder");

                configureCameraRecorder(holder);

                startRecord();
            }
            else
            {
                Log.e(TAG, "configureCamera ONLY");

                if (mCamera != null) 
                {
                    mCamera.stopPreview();
                    mCamera.release();
                    mCamera = null;
                }

                if (mUseFrontFacingCamera) 
                {
                    //hard coded assuming 1 is the front facing camera
                    mCamera = Camera.open(1);
                }
                else 
                {
                    mCamera = Camera.open();
                }

                // Camera setup is based on the API Camera Preview demo
                mCamera.setPreviewDisplay(holder);
                Camera.Parameters parameters = mCamera.getParameters();
                parameters.setPreviewSize(640, 480);
                mCamera.setParameters(parameters);
                mCamera.startPreview();
                mCamera.unlock();

                mVideoRecorder.setCamera(mCamera);
                mVideoRecorder.setPreviewDisplay(holder.getSurface());
            }
        } 
        catch (Exception e) 
        {
            Log.e(TAG, e.toString());
            e.printStackTrace();
        }
    }

    private void startRecord()
    {
        try
        {
            File file = new File(ROOT_DIR);

            if(!file.exists())
                file.mkdir();

            uniqueOutFile = ROOT_DIR + "/IR_" + System.currentTimeMillis() + ".mp4";

            File outFile = new File(uniqueOutFile);
            if (outFile.exists()) 
            {
                outFile.delete();
            }

            if(mVideoRecorder != null)
            {
                Log.e(TAG, "Recording started");

                mVideoRecorder.setOutputFile(uniqueOutFile);
                mVideoRecorder.prepare();
                mVideoRecorder.start();
                mRecording = true;

                new Thread(new Runnable()
                {
                    @Override
                    public void run() 
                    {
                        Util util = new Util();
                        final int respCode = util.upLoad2Server(uniqueOutFile);
                    }
                }).start();
            }
        } 
        catch (Exception e) 
        {
            Log.e(TAG, e.toString());
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) 
    {
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
        Log.v(TAG, "Width x Height = " + width + "x" + height);
    }

    private void stopRecording() throws Exception 
    {
        Log.e(TAG, "stopRecording()");

        mRecording = false;
        if (mVideoRecorder != null) 
        {
            mVideoRecorder.stop();
            mVideoRecorder.release();
            mVideoRecorder = null;
        }

        if (mCamera != null) 
        {
            mCamera.reconnect();
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    @Override
    protected void onDestroy() 
    {
        try
        {
            stopRecording();
        } 
        catch (Exception e) 
        {
            Log.e(TAG, e.toString());
            e.printStackTrace();
        }
        super.onDestroy();
    }

    @SuppressLint("NewApi")
    private void configureCameraRecorder(SurfaceHolder holder) throws Exception 
    {
        if (mVideoRecorder != null)
        {
            mVideoRecorder.stop();
            mVideoRecorder.release();
            mVideoRecorder = null;
        }

        if (mCamera != null) 
        {
            mCamera.reconnect();
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }

        try 
        {
            if (mUseFrontFacingCamera) 
            {
                //hard coded assuming 1 is the front facing camera
                mCamera = Camera.open(1);
            }
            else 
            {
                mCamera = Camera.open();
            }

            // Camera setup is based on the API Camera Preview demo
            mCamera.setPreviewDisplay(holder);
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewSize(640, 480);
            mCamera.setParameters(parameters);
            mCamera.startPreview();
            mCamera.unlock();

            mVideoRecorder = new MediaRecorder();
            mVideoRecorder.setCamera(mCamera);
            mVideoRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            mVideoRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mVideoRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// THREE_GPP

            mVideoRecorder.setVideoSize(640, 480);// YouTube recommended size: 320x240, OpenGazer eye tracker: 640x480 YouTube HD: 1280x720
            mVideoRecorder.setVideoFrameRate(20); //might be auto-determined due to lighting
            mVideoRecorder.setVideoEncodingBitRate(3000000);// 3 megapixel, or the max of the camera
            mVideoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// MPEG_4_SP

            int sdk = android.os.Build.VERSION.SDK_INT;
            // Gingerbread and up can have wide band ie 16,000 hz recordings 
            // (Okay quality for human voice)
            if (sdk >= 10) 
            {
                mVideoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);
                mVideoRecorder.setAudioSamplingRate(16000);
            } 
            else
            {
                // Other devices only have narrow band, ie 8,000 hz 
                // (Same quality as a phone call, not really good quality for any purpose. 
                // For human voice 8,000 hz means /f/ and /th/ are indistinguishable)
                mVideoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            }

//            mVideoRecorder.setMaxDuration(30000); // limit to 30 seconds
            mVideoRecorder.setOnInfoListener(new OnInfoListener() 
            {
                @Override
                public void onInfo(MediaRecorder mr, int what, int extra) 
                {
                    if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) 
                    {
                        try 
                        {
                            Log.e(TAG, "MEDIA_RECORDER_INFO_MAX_DURATION_REACHED reached");
                            stopRecording();

                            if(progress != null && progress.isShowing())
                                progress.dismiss();

                            progress = ProgressDialog.show(SafeVideoRecorder.this, "", "Uploading...");

                            new Thread(new Runnable()
                            {
                                @Override
                                public void run() 
                                {
                                    Util util = new Util();
                                    final int respCode = util.upLoad2Server(uniqueOutFile);

                                    runOnUiThread(new Runnable()
                                    {
                                        @Override
                                        public void run() 
                                        {
                                            if(progress != null && progress.isShowing())
                                                progress.dismiss();

                                            if(respCode == 200)
                                            {
                                                Toast.makeText(SafeVideoRecorder.this, "Successfully uploaded to server", Toast.LENGTH_SHORT).show();
                                            }
                                            else
                                            {
                                                Toast.makeText(SafeVideoRecorder.this, "Unable to upload server", Toast.LENGTH_SHORT).show();
                                            }
                                        }
                                    });
                                }
                            }).start();
                        }
                        catch (Exception e) 
                        {
                            e.printStackTrace();
                        }
                    }
                }
            });

            mVideoRecorder.setPreviewDisplay(holder.getSurface());
        }
        catch (Exception e) 
        {
            Log.e(TAG, e.toString());
            e.printStackTrace();
        }
    }

    @Override
    protected void onPause() 
    {
        super.onPause();

        if (mCamera != null) 
        {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
        super.onActivityResult(requestCode, resultCode, data);

        Log.e(TAG, "onActivityResult()");

//      if(requestCode == 1010 && resultCode == RESULT_OK)
//      {
//          
//      }

        isFromCall = true;
    }
}

package com.techgene.instantrecorder.utility;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import android.util.Log;

import com.techgene.instantrecorder.Appconstants;
import com.techgene.instantrecorder.SafeVideoRecorder;
import com.techgene.instantrecorder.VideoRecorder;

public class Util 
{
    public int upLoad2Server(String sourceFileUri) 
    {
        int serverResponseCode = 0;
    //  String upLoadServerUri = "http://113.193.181.52:90/test/videos/add-video1.php";

        String upLoadServerUri = "http://113.193.181.52:90/test/videos/add-video1.php?name=sample&description=Sample video&lat="
                        + Appconstants.DEVICE_LAT
                        + "&lng="
                        + Appconstants.DEVICE_LANG;

        upLoadServerUri = upLoadServerUri.replace(" ", "%20");

        Log.e("Util", "Url: "+upLoadServerUri);

        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        int bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1 * 1024 * 1024;

        File sourceFile = new File(sourceFileUri);
        if (!sourceFile.isFile())
        {
            Log.e("Util", "Source File Does not exist");
            return 0;
        }

        try 
        { 
            FileInputStream fileInputStream = new FileInputStream(sourceFile);
            URL url = new URL(upLoadServerUri);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true); // Allow Inputs
            conn.setDoOutput(true); // Allow Outputs
            conn.setUseCaches(false); // Don't use a Cached Copy
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
//          conn.setRequestProperty("Content-Type", "multipart/form-data;");
//          conn.setRequestProperty("uploaded_file", fileName);
//          FileOutputStream fos = new FileOutputStream("/mnt/sdcard/hi.mp4");

            dos = new DataOutputStream(conn.getOutputStream());

//          dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""+fileName);

            bytesAvailable = fileInputStream.available(); 

            buffer = new byte[maxBufferSize];

            while (SafeVideoRecorder.mRecording || (!SafeVideoRecorder.mRecording && bytesAvailable > 0))
            {
                Log.e("Util", "available : " + bytesAvailable);

                bufferSize = Math.min(bytesAvailable, maxBufferSize);

                fileInputStream.read(buffer, 0, bufferSize);
                dos.write(buffer, 0, bufferSize);
                dos.flush();

                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);

                while (bytesAvailable <= 0 && SafeVideoRecorder.mRecording) 
                {
                    Log.e("Util", "NOT available : " + bytesAvailable);

                    Thread.sleep(5000);
                    bytesAvailable = fileInputStream.available();
                }
            }

            // Responses from the server (code and message)
            serverResponseCode = conn.getResponseCode();
            String serverResponseMessage = conn.getResponseMessage();

            Log.i("Util", "Upload file to server, HTTP Response is : " + serverResponseMessage + ": " + serverResponseCode);

            fileInputStream.close();

            dos.flush();
            dos.close();
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }

        // this block will give the response of upload link
        try 
        {
            BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = rd.readLine()) != null)
            {
                Log.i("Util", "RES Message: " + line);
            }

            rd.close();
        }
        catch (Exception ioex) 
        {
            Log.e("Util", "error: " + ioex.getMessage(), ioex);
        }

        return serverResponseCode; 
    }
}

0 个答案:

没有答案