视频流通过套接字

时间:2017-07-20 08:00:09

标签: android sockets android-mediaplayer media parcelfiledescriptor

我需要通过套接字实现视频流,因为我必须在服务器端录制视频并在客户端实时流式传输,我已通过套接字成功连接对等但视频流制造麻烦,我面临以下问题:

  1. 我在API级别15和18上测试了媒体记录器,但没有在更高的Android版本上工作,它给IllegalStateException启动失败-38。

  2. Media Player无法正常工作,我已尝试使用ParcelFileDescriptor从socket获取流,并尝试将流保存到文件中以在Media Player上播放,但我没有收到任何结果。

  3. public class MainActivity2 extends Activity implements SurfaceHolder.Callback{
    
    private Handler handler = new Handler();
    private TextView text;
    private EditText input, serverIP, port;
    private Button send, connect;
    private Socket socket;
    private DataOutputStream outputStream;
    private BufferedReader inputStream;
    private String DeviceName = "Device", ipAddr;
    Thread thread;
    Integer portno;
    private Handler handler2 = new Handler();
    MediaPlayer mp;
    private SurfaceView mPreview;
    private SurfaceHolder holder;
    
    VideoView mView;
    SurfaceHolder mHolder;
    // Video variable
    MediaRecorder recorder, mMediaRecorder;
    private Handler handler3 = new Handler();
    boolean isRecording = false;
    String AudioSavePathInDevice = null;
    ParcelFileDescriptor pfd1;
    Camera mCamera;
    
    LocalServerSocket server;
    LocalSocket sender;
    
    private boolean searchNetwork() {
        log("Connecting");
        String ip = serverIP.getText().toString();
        portno = Integer.parseInt(port.getText().toString());
        try {
    
            socket = new Socket();
            socket.connect(new InetSocketAddress(ip, portno), 100);
            outputStream = new DataOutputStream(socket.getOutputStream());
            inputStream = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            DeviceName += "1";
            Log.i("Server", DeviceName);
            log("Connected");
            return true;
        } catch (Exception e) {
        }
    
        return false;
    
    }
    
    private void runNewChatServer() {
        ServerSocket serverSocket;
        try {
            WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
            String myIP = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
    
            serverSocket = new ServerSocket(portno);
            log("I am ready to connect. Please enter the IP " + myIP + " in another device to connect...");
            socket = serverSocket.accept();
            DeviceName += "2";
            log("another device Connected");
    
            pfd1 = ParcelFileDescriptor.fromSocket(socket);
            handler3.post(new Runnable() {
                @Override
                public void run() {
                    if (isRecording) {
                        // stop recording and release camera
                        mMediaRecorder.stop();  // stop the recording
                        releaseMediaRecorder(); // release the MediaRecorder object
                        mCamera.lock();         // take camera access back from MediaRecorder
    
                        // inform the user that recording has stopped
                        log("Stopped");
                        isRecording = false;
                    } else {
                        // initialize video camera
                        if (prepareVideoRecorder()) {
                            // Camera is available and unlocked, MediaRecorder is prepared,
                            // now you can start recording
                            try {
                                mMediaRecorder.start();
                                // inform the user that recording has started
                                log("Started");
                                isRecording = true;
                            } catch (IllegalStateException e) {
                                log("IllegalStateException in media start " + e.getStackTrace());
                                e.printStackTrace();
                            } catch (NullPointerException e) {
                                log("NullException in media start " + e.getMessage());
                                e.printStackTrace();
                            } catch (Exception e) {
                                log("Exception in media start " + e.getMessage());
                                e.printStackTrace();
                            }
                        } else {
                            // prepare didn't work, release the camera
                            releaseMediaRecorder();
                            // inform user
                        }
                    }
                }
    
            });
    
        }
        catch (Exception e) {
            final String msg = e.getMessage();
            log("Oops.Connection interrupted. Please reconnect your phones." + msg);
            e.printStackTrace();
        }
    
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        text = (TextView) findViewById(R.id.textin);
        input = (EditText) findViewById(R.id.textout);
        send = (Button) findViewById(R.id.send);
        connect = (Button) findViewById(R.id.connect);
        serverIP = (EditText)findViewById(R.id.serverip);
        port = (EditText)findViewById(R.id.port);
        mPreview = (SurfaceView) findViewById(R.id.surfaceView1);
        holder = mPreview.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        mp = new MediaPlayer();
    
    
        mView = (VideoView) findViewById(R.id.videoView);
        mHolder = mView.getHolder();
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    
    
        thread = new Thread(new Runnable() {
    
            @Override
            public void run() {
                try {
                    if (!searchNetwork()) {
                        runNewChatServer();
                    }
                    else
                    {
                        prepareMediaPlayer();
                    }
    
                    outputStream = new DataOutputStream(
                            socket.getOutputStream());
                    inputStream = new BufferedReader(new InputStreamReader(
                            socket.getInputStream()));
                    while (true) {
                        String Message = inputStream.readLine();
                        if (Message != null) {
                            log(Message);
                        }
                    }
    
                } catch (IOException e) {
                    log("Error: IO Exception");
                    e.printStackTrace();
                }
                catch (Exception e) {
                    log("Error: Exception");
                    e.printStackTrace();
                }
            }
        });
        send.setOnClickListener(new View.OnClickListener() {
    
            @Override
            public void onClick(View arg0) {
                if (outputStream == null) {
                    return;
                }
                try {
                    String Message = input.getText().toString() + "\n";
                    outputStream.write(Message.getBytes());
                    log2(input.getText().toString());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                input.setText("");
            }
        });
    
        connect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                ipAddr = serverIP.getText().toString();
                thread.start();
            }
        });
    
    
    }
    
    private void log(final String message) {
        handler.post(new Runnable() {
            String DeviceName2 = "";
    
            @Override
            public void run() {
                if (DeviceName.equals("Device1")) {
                    DeviceName2 = "Device2";
                } else if (DeviceName.equals("Device2")) {
                    DeviceName2 = "Device1";
                } else {
                    DeviceName2 = "UnknowDevice";
                }
    
                text.setText(text.getText() + "\n" + DeviceName2 + " :"
                        + message);
    
            }
        });
    }
    private void log2(final String message) {
        handler.post(new Runnable() {
    
            @Override
            public void run() {
                text.setText(text.getText() + "\n" + "you" + " :"
                        + message);
    
            }
        });
    }
    
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.exit(0);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
    
    private boolean prepareVideoRecorder(){
    
        mMediaRecorder = new MediaRecorder();
        mCamera = getCameraInstance();
    
        // Step 1: Unlock and set camera to MediaRecorder
        mCamera.unlock();
        mMediaRecorder.setCamera(mCamera);
    
        // Step 2: Set sources
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    
        // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
        mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
    
    
        mMediaRecorder.setOutputFile(pfd1.getFileDescriptor());
    
        // Step 5: Set the preview output
        mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
    
        // Step 6: Prepare configured MediaRecorder
        try {
            mMediaRecorder.prepare();
        } catch (IllegalStateException e) {
            log("IllegalStateException preparing MediaRecorder: " + e.getMessage());
            releaseMediaRecorder();
            return false;
        } catch (IOException e) {
            log("IOException preparing MediaRecorder: " + e.getMessage());
            releaseMediaRecorder();
            return false;
        }
        return true;
    }
    
    private boolean prepareMediaPlayer() {
    
        try {
            ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
            pfd.getFileDescriptor().sync();
            mp.setDataSource(pfd.getFileDescriptor());
            pfd.close();
            mp.setDisplay(mHolder);
            mp.prepareAsync();
            mp.start();
    
            return true;
        }catch(Exception ex){
            ex.printStackTrace();
            return false;
        }
    }
    
    /** A safe way to get an instance of the Camera object. */
    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
        }
        catch (Exception e){
            Log.d("CameraInstance", e.getMessage());
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaRecorder();       // if you are using MediaRecorder, release it first
        releaseCamera();              // release the camera immediately on pause event
    }
    
    private void releaseMediaRecorder(){
        if (mMediaRecorder != null) {
            mMediaRecorder.reset();   // clear recorder configuration
            mMediaRecorder.release(); // release the recorder object
            mMediaRecorder = null;
            mCamera.lock();           // lock camera for later use
        }
    }
    
    private void releaseCamera(){
        if (mCamera != null){
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
    }
    
    public void surfaceCreated(SurfaceHolder holder) {
    
       /* try {
            prepareVideoRecorder();
        } catch (IllegalStateException e) {
            e.printStackTrace();
            log("IllegalStateException preparing MediaRecorder2: " + e.getMessage());
            finish();
        }*/
    }
    
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
    }
    
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (isRecording) {
            mMediaRecorder.stop();
            isRecording = false;
        }
        releaseMediaRecorder();
        releaseCamera();
        finish();
    }
    }
    

    我还使用以下代码片段将输入流保存到文件中以在Media Player上播放,但它对我没有用。

    File downloadingMediaFile = File.createTempFile("downloading", ".mp4");
    FileOutputStream out = new FileOutputStream(downloadingMediaFile);
    IOUtils.copy(socket.getInputStream(), out);
    mp.setDataSource(out.getFD());
    

    我已尝试使用此代码段在Lollipop或更高版本的API上录制视频流,但它也无法正常工作。

    ParcelFileDescriptor[] parcelFileDescriptors = new ParcelFileDescriptor[0];
    try {
    parcelFileDescriptors = ParcelFileDescriptor.createPipe();
    } catch (IOException e) {
    e.printStackTrace();
    }
    ParcelFileDescriptor parcelRead = new 
    ParcelFileDescriptor(parcelFileDescriptors[0]);
    ParcelFileDescriptor parcelWrite  = new 
    ParcelFileDescriptor(parcelFileDescriptors[1]);
    mMediarecorder.setOutputFile(parcelWrite.fromSocket(socket).getFileDescriptor());
    

0 个答案:

没有答案