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.jingleold.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.jingleold.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 final 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 @Override 066 public synchronized void update(SessionEvent evt) { 067 if (evt instanceof NewParticipantEvent) { 068 Participant p = ((NewParticipantEvent) evt).getParticipant(); 069 LOGGER.fine(" - A new participant had just joined: " + p.getCNAME()); 070 } 071 } 072 073 /** 074 * ReceiveStreamListener. 075 */ 076 @Override 077 public synchronized void update(ReceiveStreamEvent evt) { 078 079 Participant participant = evt.getParticipant(); // could be null. 080 ReceiveStream stream = evt.getReceiveStream(); // could be null. 081 082 if (evt instanceof RemotePayloadChangeEvent) { 083 LOGGER.severe(" - Received an RTP PayloadChangeEvent."); 084 LOGGER.severe("Sorry, cannot handle payload change."); 085 086 } 087 else if (evt instanceof NewReceiveStreamEvent) { 088 089 try { 090 stream = evt.getReceiveStream(); 091 DataSource ds = stream.getDataSource(); 092 093 // Find out the formats. 094 RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl"); 095 if (ctl != null) { 096 LOGGER.severe(" - Received new RTP stream: " + ctl.getFormat()); 097 } 098 else 099 LOGGER.severe(" - Received new RTP stream"); 100 101 if (participant == null) 102 LOGGER.severe(" The sender of this stream had yet to be identified."); 103 else { 104 LOGGER.severe(" The stream comes from: " + participant.getCNAME()); 105 } 106 107 // create a player by passing datasource to the Media Manager 108 Player p = javax.media.Manager.createPlayer(ds); 109 if (p == null) 110 return; 111 112 p.addControllerListener(this); 113 p.realize(); 114 jingleMediaSession.mediaReceived(participant != null ? participant.getCNAME() : ""); 115 116 // Notify initialize() that a new stream had arrived. 117 synchronized (dataSync) { 118 dataReceived = true; 119 dataSync.notifyAll(); 120 } 121 122 } 123 catch (Exception e) { 124 LOGGER.severe("NewReceiveStreamEvent exception " + e.getMessage()); 125 return; 126 } 127 128 } 129 else if (evt instanceof StreamMappedEvent) { 130 131 if (stream != null && stream.getDataSource() != null) { 132 DataSource ds = stream.getDataSource(); 133 // Find out the formats. 134 RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl"); 135 LOGGER.severe(" - The previously unidentified stream "); 136 if (ctl != null) 137 LOGGER.severe(" " + ctl.getFormat()); 138 LOGGER.severe(" had now been identified as sent by: " + participant.getCNAME()); 139 } 140 } 141 else if (evt instanceof ByeEvent) { 142 143 LOGGER.severe(" - Got \"bye\" from: " + participant.getCNAME()); 144 145 } 146 147 } 148 149 /** 150 * ControllerListener for the Players. 151 */ 152 @Override 153 public synchronized void controllerUpdate(ControllerEvent ce) { 154 155 Player p = (Player) ce.getSourceController(); 156 157 if (p == null) 158 return; 159 160 // Get this when the internal players are realized. 161 if (ce instanceof RealizeCompleteEvent) { 162 p.start(); 163 } 164 165 if (ce instanceof ControllerErrorEvent) { 166 p.removeControllerListener(this); 167 LOGGER.severe("Receiver internal error: " + ce); 168 } 169 170 } 171}