package com.example.licodeclient; import org.json.JSONException; import org.json.JSONObject; import org.webrtc.MediaConstraints; import org.webrtc.MediaStream; import org.webrtc.PeerConnection; import org.webrtc.SdpObserver; import org.webrtc.VideoRenderer; public class StreamDescription implements StreamDescriptionInterface { /** current state of the stream */ private StreamState mState = StreamState.UNKNOWN; /** identifier for this stream */ private String mId; /** has data? */ private boolean mData; /** has video? */ private boolean mVideo; /** has screen stream? */ private boolean mScreen; /** has audio? */ private boolean mAudio; /** the attribute information */ private JSONObject mAttributes = new JSONObject(); /** the nick attached to this stream - if any */ private String mNick; /** * flag to store if stream is outgoing (true, local) or incoming (false, * remote) */ private boolean mLocal; /** sdp constraints for the sdp */ private MediaConstraints mSdpConstraints; /** flag - stores if audio is currently allowed to play, or not */ private boolean mAudioActive = true; public static StreamDescription parseJson(JSONObject arg) { String id = null; boolean data = false; boolean video = false; boolean audio = false; boolean screen = false; JSONObject attr = null; String nick = null; try { id = arg.getString("id"); } catch (JSONException e) { } try { data = arg.getBoolean("data"); } catch (JSONException e3) { } try { video = arg.getBoolean("video"); } catch (JSONException e2) { } try { audio = arg.getBoolean("audio"); } catch (JSONException e1) { } try { screen = arg.getBoolean("screen"); } catch (JSONException e) { } try { attr = arg.getJSONObject("attributes"); if (attr != null) { nick = attr.getString("nick"); } } catch (JSONException e) { } return new StreamDescription(id, data, video, audio, screen, attr, nick); } public StreamDescription(String id, boolean data, boolean video, boolean audio, boolean screen, JSONObject attr, String nick) { mId = id; mData = data; mVideo = video; mAudio = audio; mScreen = screen; if (attr != null) { mAttributes = attr; } mNick = nick; } /* * (non-Javadoc) * * @see * com.knuddels.android.activities.webrtc.StreamDescriptionInteface#toJson() */ @Override public JSONObject toJson() { JSONObject result = new JSONObject(); try { result.put("data", mData); result.put("video", mVideo); result.put("audio", mAudio); result.put("screen", mScreen); if (mAttributes == null) { mAttributes = new JSONObject(); } mAttributes.put("nick", mNick); result.put("attributes", mAttributes); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; } /* * (non-Javadoc) * * @see * com.knuddels.android.activities.webrtc.StreamDescriptionInteface#getId() */ @Override public String getId() { return mId; } /* * (non-Javadoc) * * @see * com.knuddels.android.activities.webrtc.StreamDescriptionInteface#setId * (java.lang.String) */ @Override public void setId(String newId) { if (mLocal) { mId = newId; } else { throw new UnsupportedOperationException( "May not change id of a non-local stream!"); } } /* * (non-Javadoc) * * @see * com.knuddels.android.activities.webrtc.StreamDescriptionInteface#isLocal * () */ @Override public boolean isLocal() { return mLocal; } /* * (non-Javadoc) * * @see * com.knuddels.android.activities.webrtc.StreamDescriptionInteface#toJsonOffer * (java.lang.String) */ @Override public JSONObject toJsonOffer(String state) { JSONObject result = new JSONObject(); try { if (state != null) { result.put("state", state); } result.put("data", mData); result.put("audio", mAudio); result.put("video", mVideo); if (mAttributes == null) { mAttributes = new JSONObject(); } mAttributes.put("nick", mNick); result.put("attributes", mAttributes); } catch (JSONException jex) { // TODO jex.printStackTrace(); } return result; } public PeerConnection pc = null; /** the active media stream */ private volatile MediaStream mMediaStream; /** currently set video renderer */ private VideoRenderer mRenderer; /** access the sdp's constraints */ public MediaConstraints sdpConstraints() { return mSdpConstraints; } public void initLocal(PeerConnection pc, SdpObserver sdpObserver) { mLocal = true; mState = StreamState.LOCAL; this.pc = pc; mSdpConstraints = new MediaConstraints(); mSdpConstraints.mandatory.add(new MediaConstraints.KeyValuePair( "OfferToReceiveAudio", "true")); mSdpConstraints.mandatory.add(new MediaConstraints.KeyValuePair( "OfferToReceiveVideo", "true")); pc.createOffer(sdpObserver, mSdpConstraints); } public void initRemote(PeerConnection pc, SdpObserver sdpObserver) { mLocal = false; mState = StreamState.OPENING; this.pc = pc; mSdpConstraints = new MediaConstraints(); mSdpConstraints.mandatory.add(new MediaConstraints.KeyValuePair( "OfferToReceiveAudio", "true")); mSdpConstraints.mandatory.add(new MediaConstraints.KeyValuePair( "OfferToReceiveVideo", "true")); pc.createOffer(sdpObserver, mSdpConstraints); } /** sets the associated media stream - if prepared */ public void setMedia(MediaStream media) { mMediaStream = media; } /** access the media stream - may be null */ public MediaStream getMedia() { return mMediaStream; } /** attach a renderer to the media */ public synchronized void attachRenderer( LicodeConnector.VideoCallbacks videoCallbacks) { if (mRenderer != null) { return; } if (mMediaStream != null && mMediaStream.videoTracks.size() == 1) { mState = StreamState.ACTIVE; mRenderer = new VideoRenderer(videoCallbacks); mMediaStream.videoTracks.get(0).addRenderer(mRenderer); } } /** attaches a complete renderer */ public synchronized void attachLocalRenderer(VideoRenderer renderer) { if (mRenderer != null) { return; } mRenderer = renderer; } /* * (non-Javadoc) * * @see com.knuddels.android.activities.webrtc.StreamDescriptionInteface# * detachRenderer() */ @Override public synchronized void detachRenderer() { if (mRenderer != null && mMediaStream != null && mMediaStream.videoTracks.size() == 1) { mMediaStream.videoTracks.get(0).removeRenderer(mRenderer); } mRenderer = null; } /* * (non-Javadoc) * * @see * com.knuddels.android.activities.webrtc.StreamDescriptionInteface#onClosing * () */ @Override public void onClosing() { mState = StreamState.CLOSING; } /* * (non-Javadoc) * * @see * com.knuddels.android.activities.webrtc.StreamDescriptionInteface#onDestroyed * () */ @Override public void onDestroyed() { mState = StreamState.DESTROYED; mMediaStream = null; } /* * (non-Javadoc) * * @see * com.knuddels.android.activities.webrtc.StreamDescriptionInteface#onDisable * () */ @Override public void onDisable() { mState = StreamState.BLOCKED; mMediaStream = null; } /* * (non-Javadoc) * * @see * com.knuddels.android.activities.webrtc.StreamDescriptionInteface#getState * () */ @Override public StreamState getState() { return mState; } /* * (non-Javadoc) * * @see * com.knuddels.android.activities.webrtc.StreamDescriptionInteface#toggleAudio * () */ @Override public void toggleAudio() { setAudioActive(!mAudioActive); } /* * (non-Javadoc) * * @see com.knuddels.android.activities.webrtc.StreamDescriptionInteface# * setAudioActive(boolean) */ @Override public void setAudioActive(boolean audioActive) { mAudioActive = audioActive; if (mMediaStream != null && mMediaStream.audioTracks.size() == 1) { mMediaStream.audioTracks.get(0).setEnabled(mAudioActive); } } /* * (non-Javadoc) * * @see com.knuddels.android.activities.webrtc.StreamDescriptionInteface# * isAudioActive() */ @Override public boolean isAudioActive() { return mAudioActive; } @Override public String getNick() { if (mNick != null) { return mNick; } if (mAttributes != null) { try { return mAttributes.getString("nick"); } catch (JSONException e) { } } return null; } /** check if this stream has been abandoned by the video server */ public boolean isClosing() { return mState == StreamState.CLOSING; } }