Android Open Source - spydroid-ipcamera Media Stream






From Project

Back to project page spydroid-ipcamera.

License

The source code is released under:

GNU General Public License

If you think the Android project spydroid-ipcamera listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2011-2014 GUIGUI Simon, fyhertz@gmail.com
 * /*  ww  w  . j a va2s  .c o  m*/
 * This file is part of libstreaming (https://github.com/fyhertz/libstreaming)
 * 
 * Spydroid is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This source code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this source code; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package net.majorkernelpanic.streaming;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Random;

import net.majorkernelpanic.streaming.audio.AudioStream;
import net.majorkernelpanic.streaming.rtp.AbstractPacketizer;
import net.majorkernelpanic.streaming.video.VideoStream;
import android.annotation.SuppressLint;
import android.media.MediaCodec;
import android.media.MediaRecorder;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.util.Log;

/**
 * A MediaRecorder that streams what it records using a packetizer from the rtp package.
 * You can't use this class directly !
 */
public abstract class MediaStream implements Stream {

  protected static final String TAG = "MediaStream";

  /** Raw audio/video will be encoded using the MediaRecorder API. */
  public static final byte MODE_MEDIARECORDER_API = 0x01;

  /** Raw audio/video will be encoded using the MediaCodec API with buffers. */
  public static final byte MODE_MEDIACODEC_API = 0x02;

  /** Raw audio/video will be encoded using the MediaCode API with a surface. */
  public static final byte MODE_MEDIACODEC_API_2 = 0x05;

  /** Prefix that will be used for all shared preferences saved by libstreaming */
  protected static final String PREF_PREFIX = "libstreaming-";

  /** The packetizer that will read the output of the camera and send RTP packets over the networkd. */
  protected AbstractPacketizer mPacketizer = null;

  protected static byte sSuggestedMode = MODE_MEDIARECORDER_API;
  protected byte mMode, mRequestedMode;

  protected boolean mStreaming = false, mConfigured = false;
  protected int mRtpPort = 0, mRtcpPort = 0;
  protected InetAddress mDestination;
  protected LocalSocket mReceiver, mSender = null;
  private LocalServerSocket mLss = null;
  private int mSocketId, mTTL = 64;

  protected MediaRecorder mMediaRecorder;
  protected MediaCodec mMediaCodec;
  
  static {
    // We determine wether or not the MediaCodec API should be used
    try {
      Class.forName("android.media.MediaCodec");
      // Will be set to MODE_MEDIACODEC_API at some point...
      sSuggestedMode = MODE_MEDIACODEC_API;
      Log.i(TAG,"Phone supports the MediaCoded API");
    } catch (ClassNotFoundException e) {
      sSuggestedMode = MODE_MEDIARECORDER_API;
      Log.i(TAG,"Phone does not support the MediaCodec API");
    }
  }

  public MediaStream() {
    mRequestedMode = sSuggestedMode;
    mMode = sSuggestedMode;
  }

  /** 
   * Sets the destination ip address of the stream.
   * @param dest The destination address of the stream 
   */  
  public void setDestinationAddress(InetAddress dest) {
    mDestination = dest;
  }

  /** 
   * Sets the destination ports of the stream.
   * If an odd number is supplied for the destination port then the next 
   * lower even number will be used for RTP and it will be used for RTCP.
   * If an even number is supplied, it will be used for RTP and the next odd
   * number will be used for RTCP.
   * @param dport The destination port
   */
  public void setDestinationPorts(int dport) {
    if (dport % 2 == 1) {
      mRtpPort = dport-1;
      mRtcpPort = dport;
    } else {
      mRtpPort = dport;
      mRtcpPort = dport+1;
    }
  }

  /**
   * Sets the destination ports of the stream.
   * @param rtpPort Destination port that will be used for RTP
   * @param rtcpPort Destination port that will be used for RTCP
   */
  public void setDestinationPorts(int rtpPort, int rtcpPort) {
    mRtpPort = rtpPort;
    mRtcpPort = rtcpPort;
  }  

  /**
   * Sets the Time To Live of packets sent over the network.
   * @param ttl The time to live
   * @throws IOException
   */
  public void setTimeToLive(int ttl) throws IOException {
    mTTL = ttl;
  }

  /** 
   * Returns a pair of destination ports, the first one is the 
   * one used for RTP and the second one is used for RTCP. 
   **/
  public int[] getDestinationPorts() {
    return new int[] {
        mRtpPort,
        mRtcpPort
    };
  }

  /** 
   * Returns a pair of source ports, the first one is the 
   * one used for RTP and the second one is used for RTCP. 
   **/  
  public int[] getLocalPorts() {
    return new int[] {
        this.mPacketizer.getRtpSocket().getLocalPort(),
        this.mPacketizer.getRtcpSocket().getLocalPort()
    };
  }

  /**
   * Sets the streaming method that will be used.
   * 
   * If the mode is set to {@link #MODE_MEDIARECORDER_API}, raw audio/video will be encoded 
   * using the MediaRecorder API. <br />
   * 
   * If the mode is set to {@link #MODE_MEDIACODEC_API} or to {@link #MODE_MEDIACODEC_API_2}, 
   * audio/video will be encoded with using the MediaCodec. <br />
   * 
   * The {@link #MODE_MEDIACODEC_API_2} mode only concerns {@link VideoStream}, it makes 
   * use of the createInputSurface() method of the MediaCodec API (Android 4.3 is needed there). <br />
   * 
   * @param mode Can be {@link #MODE_MEDIARECORDER_API}, {@link #MODE_MEDIACODEC_API} or {@link #MODE_MEDIACODEC_API_2} 
   */
  public void setStreamingMethod(byte mode) {
    mRequestedMode = mode;
  }

  /**
   * Returns the packetizer associated with the {@link MediaStream}.
   * @return The packetizer
   */
  public AbstractPacketizer getPacketizer() { 
    return mPacketizer;
  }

  /**
   * Returns an approximation of the bit rate consumed by the stream in bit per seconde.
   */
  public long getBitrate() {
    return !mStreaming ? 0 : mPacketizer.getRtpSocket().getBitrate(); 
  }

  /**
   * Indicates if the {@link MediaStream} is streaming.
   * @return A boolean indicating if the {@link MediaStream} is streaming
   */
  public boolean isStreaming() {
    return mStreaming;
  }

  /**
   * Configures the stream with the settings supplied with 
   * {@link VideoStream#setVideoQuality(net.majorkernelpanic.streaming.video.VideoQuality)}
   * for a {@link VideoStream} and {@link AudioStream#setAudioQuality(net.majorkernelpanic.streaming.audio.AudioQuality)}
   * for a {@link AudioStream}.
   */
  public synchronized void configure() throws IllegalStateException, IOException {
    if (mStreaming) throw new IllegalStateException("Can't be called while streaming.");
    mMode = mRequestedMode;
    mConfigured = true;
  }
  
  /** Starts the stream. */
  public synchronized void start() throws IllegalStateException, IOException {
    
    if (mDestination==null)
      throw new IllegalStateException("No destination ip address set for the stream !");

    if (mRtpPort<=0 || mRtcpPort<=0)
      throw new IllegalStateException("No destination ports set for the stream !");

    mPacketizer.setTimeToLive(mTTL);
    
    if (mMode != MODE_MEDIARECORDER_API) {
      encodeWithMediaCodec();
    } else {
      encodeWithMediaRecorder();
    }

  }

  /** Stops the stream. */
  @SuppressLint("NewApi") 
  public synchronized  void stop() {
    if (mStreaming) {
      try {
        if (mMode==MODE_MEDIARECORDER_API) {
          mMediaRecorder.stop();
          mMediaRecorder.release();
          mMediaRecorder = null;
          closeSockets();
          mPacketizer.stop();
        } else {
          mPacketizer.stop();
          mMediaCodec.stop();
          mMediaCodec.release();
          mMediaCodec = null;
        }
      } catch (Exception e) {
        e.printStackTrace();
      }  
      mStreaming = false;
    }
  }
 
  protected abstract void encodeWithMediaRecorder() throws IOException;

  protected abstract void encodeWithMediaCodec() throws IOException;
  
  /**
   * Returns a description of the stream using SDP. 
   * This method can only be called after {@link Stream#configure()}.
   * @throws IllegalStateException Thrown when {@link Stream#configure()} wa not called.
   */
  public abstract String getSessionDescription();
  
  /**
   * Returns the SSRC of the underlying {@link net.majorkernelpanic.streaming.rtp.RtpSocket}.
   * @return the SSRC of the stream
   */
  public int getSSRC() {
    return getPacketizer().getSSRC();
  }
  
  protected void createSockets() throws IOException {

    final String LOCAL_ADDR = "net.majorkernelpanic.streaming-";

    for (int i=0;i<10;i++) {
      try {
        mSocketId = new Random().nextInt();
        mLss = new LocalServerSocket(LOCAL_ADDR+mSocketId);
        break;
      } catch (IOException e1) {}
    }

    mReceiver = new LocalSocket();
    mReceiver.connect( new LocalSocketAddress(LOCAL_ADDR+mSocketId));
    mReceiver.setReceiveBufferSize(500000);
    mReceiver.setSoTimeout(3000);
    mSender = mLss.accept();
    mSender.setSendBufferSize(500000);
  }

  protected void closeSockets() {
    try {
      mReceiver.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
    try {
      mSender.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
    try {
      mLss.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
    mLss = null;
    mSender = null;
    mReceiver = null;
  }
  
}




Java Source Code List

net.majorkernelpanic.http.ModAssetServer.java
net.majorkernelpanic.http.ModInternationalization.java
net.majorkernelpanic.http.ModSSL.java
net.majorkernelpanic.http.TinyHttpServer.java
net.majorkernelpanic.spydroid.SpydroidApplication.java
net.majorkernelpanic.spydroid.Utilities.java
net.majorkernelpanic.spydroid.api.CustomHttpServer.java
net.majorkernelpanic.spydroid.api.CustomRtspServer.java
net.majorkernelpanic.spydroid.api.RequestHandler.java
net.majorkernelpanic.spydroid.ui.AboutFragment.java
net.majorkernelpanic.spydroid.ui.HandsetFragment.java
net.majorkernelpanic.spydroid.ui.OptionsActivity.java
net.majorkernelpanic.spydroid.ui.PreviewFragment.java
net.majorkernelpanic.spydroid.ui.SpydroidActivity.java
net.majorkernelpanic.spydroid.ui.TabletFragment.java
net.majorkernelpanic.streaming.MediaStream.java
net.majorkernelpanic.streaming.SessionBuilder.java
net.majorkernelpanic.streaming.Session.java
net.majorkernelpanic.streaming.Stream.java
net.majorkernelpanic.streaming.audio.AACStream.java
net.majorkernelpanic.streaming.audio.AMRNBStream.java
net.majorkernelpanic.streaming.audio.AudioQuality.java
net.majorkernelpanic.streaming.audio.AudioStream.java
net.majorkernelpanic.streaming.exceptions.CameraInUseException.java
net.majorkernelpanic.streaming.exceptions.ConfNotSupportedException.java
net.majorkernelpanic.streaming.exceptions.InvalidSurfaceException.java
net.majorkernelpanic.streaming.exceptions.StorageUnavailableException.java
net.majorkernelpanic.streaming.gl.SurfaceManager.java
net.majorkernelpanic.streaming.gl.SurfaceView.java
net.majorkernelpanic.streaming.gl.TextureManager.java
net.majorkernelpanic.streaming.hw.CodecManager.java
net.majorkernelpanic.streaming.hw.EncoderDebugger.java
net.majorkernelpanic.streaming.hw.NV21Convertor.java
net.majorkernelpanic.streaming.mp4.MP4Config.java
net.majorkernelpanic.streaming.mp4.MP4Parser.java
net.majorkernelpanic.streaming.rtcp.SenderReport.java
net.majorkernelpanic.streaming.rtp.AACADTSPacketizer.java
net.majorkernelpanic.streaming.rtp.AACLATMPacketizer.java
net.majorkernelpanic.streaming.rtp.AMRNBPacketizer.java
net.majorkernelpanic.streaming.rtp.AbstractPacketizer.java
net.majorkernelpanic.streaming.rtp.H263Packetizer.java
net.majorkernelpanic.streaming.rtp.H264Packetizer.java
net.majorkernelpanic.streaming.rtp.MediaCodecInputStream.java
net.majorkernelpanic.streaming.rtp.RtpSocket.java
net.majorkernelpanic.streaming.rtsp.RtspClient.java
net.majorkernelpanic.streaming.rtsp.RtspServer.java
net.majorkernelpanic.streaming.rtsp.UriParser.java
net.majorkernelpanic.streaming.video.CodecManager.java
net.majorkernelpanic.streaming.video.H263Stream.java
net.majorkernelpanic.streaming.video.H264Stream.java
net.majorkernelpanic.streaming.video.VideoQuality.java
net.majorkernelpanic.streaming.video.VideoStream.java