001/** 002 * 003 * Copyright 2003-2006 Jive Software. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.jingle.mediaimpl.jmf; 018 019import java.util.logging.Logger; 020 021import javax.media.ControllerErrorEvent; 022import javax.media.ControllerEvent; 023import javax.media.ControllerListener; 024import javax.media.Player; 025import javax.media.RealizeCompleteEvent; 026import javax.media.protocol.DataSource; 027import javax.media.rtp.Participant; 028import javax.media.rtp.RTPControl; 029import javax.media.rtp.ReceiveStream; 030import javax.media.rtp.ReceiveStreamListener; 031import javax.media.rtp.SessionListener; 032import javax.media.rtp.event.ByeEvent; 033import javax.media.rtp.event.NewParticipantEvent; 034import javax.media.rtp.event.NewReceiveStreamEvent; 035import javax.media.rtp.event.ReceiveStreamEvent; 036import javax.media.rtp.event.RemotePayloadChangeEvent; 037import javax.media.rtp.event.SessionEvent; 038import javax.media.rtp.event.StreamMappedEvent; 039 040import org.jivesoftware.smackx.jingle.media.JingleMediaSession; 041 042/** 043 * This class implements receive methods and listeners to be used in AudioChannel 044 * 045 * @author Thiago Camargo 046 */ 047public class AudioReceiver implements ReceiveStreamListener, SessionListener, 048 ControllerListener { 049 050 private static final Logger LOGGER = Logger.getLogger(AudioReceiver.class.getName()); 051 052 boolean dataReceived = false; 053 054 Object dataSync; 055 JingleMediaSession jingleMediaSession; 056 057 public AudioReceiver(final Object dataSync, final JingleMediaSession jingleMediaSession) { 058 this.dataSync = dataSync; 059 this.jingleMediaSession = jingleMediaSession; 060 } 061 062 /** 063 * JingleSessionListener. 064 */ 065 public synchronized void update(SessionEvent evt) { 066 if (evt instanceof NewParticipantEvent) { 067 Participant p = ((NewParticipantEvent) evt).getParticipant(); 068 LOGGER.fine(" - A new participant had just joined: " + p.getCNAME()); 069 } 070 } 071 072 /** 073 * ReceiveStreamListener 074 */ 075 public synchronized void update(ReceiveStreamEvent evt) { 076 077 Participant participant = evt.getParticipant(); // could be null. 078 ReceiveStream stream = evt.getReceiveStream(); // could be null. 079 080 if (evt instanceof RemotePayloadChangeEvent) { 081 LOGGER.severe(" - Received an RTP PayloadChangeEvent."); 082 LOGGER.severe("Sorry, cannot handle payload change."); 083 084 } 085 else if (evt instanceof NewReceiveStreamEvent) { 086 087 try { 088 stream = evt.getReceiveStream(); 089 DataSource ds = stream.getDataSource(); 090 091 // Find out the formats. 092 RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl"); 093 if (ctl != null) { 094 LOGGER.severe(" - Recevied new RTP stream: " + ctl.getFormat()); 095 } 096 else 097 LOGGER.severe(" - Recevied new RTP stream"); 098 099 if (participant == null) 100 LOGGER.severe(" The sender of this stream had yet to be identified."); 101 else { 102 LOGGER.severe(" The stream comes from: " + participant.getCNAME()); 103 } 104 105 // create a player by passing datasource to the Media Manager 106 Player p = javax.media.Manager.createPlayer(ds); 107 if (p == null) 108 return; 109 110 p.addControllerListener(this); 111 p.realize(); 112 jingleMediaSession.mediaReceived(participant != null ? participant.getCNAME() : ""); 113 114 // Notify intialize() that a new stream had arrived. 115 synchronized (dataSync) { 116 dataReceived = true; 117 dataSync.notifyAll(); 118 } 119 120 } 121 catch (Exception e) { 122 LOGGER.severe("NewReceiveStreamEvent exception " + e.getMessage()); 123 return; 124 } 125 126 } 127 else if (evt instanceof StreamMappedEvent) { 128 129 if (stream != null && stream.getDataSource() != null) { 130 DataSource ds = stream.getDataSource(); 131 // Find out the formats. 132 RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl"); 133 LOGGER.severe(" - The previously unidentified stream "); 134 if (ctl != null) 135 LOGGER.severe(" " + ctl.getFormat()); 136 LOGGER.severe(" had now been identified as sent by: " + participant.getCNAME()); 137 } 138 } 139 else if (evt instanceof ByeEvent) { 140 141 LOGGER.severe(" - Got \"bye\" from: " + participant.getCNAME()); 142 143 } 144 145 } 146 147 /** 148 * ControllerListener for the Players. 149 */ 150 public synchronized void controllerUpdate(ControllerEvent ce) { 151 152 Player p = (Player) ce.getSourceController(); 153 154 if (p == null) 155 return; 156 157 // Get this when the internal players are realized. 158 if (ce instanceof RealizeCompleteEvent) { 159 p.start(); 160 } 161 162 if (ce instanceof ControllerErrorEvent) { 163 p.removeControllerListener(this); 164 LOGGER.severe("Receiver internal error: " + ce); 165 } 166 167 } 168}