Guest User

Untitled

a guest
Jul 20th, 2018
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.56 KB | None | 0 0
  1. import java.io.IOException;
  2. import java.io.UnsupportedEncodingException;
  3. import java.net.URI;
  4. import java.net.URLEncoder;
  5.  
  6. import javax.media.mscontrol.EventType;
  7. import javax.media.mscontrol.MediaConfigException;
  8. import javax.media.mscontrol.MediaEventListener;
  9. import javax.media.mscontrol.MediaSession;
  10. import javax.media.mscontrol.MsControlException;
  11. import javax.media.mscontrol.MsControlFactory;
  12. import javax.media.mscontrol.Parameter;
  13. import javax.media.mscontrol.Parameters;
  14. import javax.media.mscontrol.join.Joinable.Direction;
  15. import javax.media.mscontrol.mediagroup.MediaGroup;
  16. import javax.media.mscontrol.mediagroup.Player;
  17. import javax.media.mscontrol.mediagroup.PlayerEvent;
  18. import javax.media.mscontrol.mediagroup.signals.SignalDetector;
  19. import javax.media.mscontrol.mediagroup.signals.SignalDetectorEvent;
  20. import javax.media.mscontrol.networkconnection.NetworkConnection;
  21. import javax.media.mscontrol.networkconnection.SdpException;
  22. import javax.media.mscontrol.networkconnection.SdpPortManagerEvent;
  23. import javax.media.mscontrol.networkconnection.SdpPortManagerException;
  24. import javax.media.mscontrol.resource.RTC;
  25. import javax.media.mscontrol.spi.DriverManager;
  26. import javax.servlet.ServletConfig;
  27. import javax.servlet.ServletException;
  28. import javax.servlet.sip.SipServlet;
  29. import javax.servlet.sip.SipServletRequest;
  30. import javax.servlet.sip.SipServletResponse;
  31. import javax.servlet.sip.SipSession;
  32.  
  33. public class PlayerJumpServlet extends SipServlet {
  34.  
  35. private static final long serialVersionUID = -1819868571070478092L;
  36.  
  37. // Each incoming call goes through the following states:
  38. public final static String WAITING_FOR_MEDIA_SERVER = "WAITING_FOR_MEDIA_SERVER";
  39.  
  40. public final static String WAITING_FOR_ACK = "WAITING_FOR_ACK";
  41.  
  42. public final static String WAITING_FOR_MEDIA_SERVER_2 = "WAITING_FOR_MEDIA_SERVER_2";
  43.  
  44. public final static String DIALOG = "DIALOG";
  45.  
  46. public final static String BYE_SENT = "BYE_SENT";
  47.  
  48. public final static String CONFIG_AUDIO_FILE = "audio.file.url";
  49.  
  50. public final static String CONFIG_JUMP_TIME = "jump.time";
  51.  
  52. // Reference the media session factory initialized from init()
  53. protected MsControlFactory msControlFactory;
  54.  
  55. // Listener for SdpPortManager events
  56. private MyRtpPortsListener networkConnectionListener;
  57.  
  58. // Listener for MediaGroup events
  59. protected MyPlayerListener playerListener;
  60.  
  61. protected MySigDetListener sigDetListener;
  62.  
  63. // The prompt to play
  64. protected URI promptAudioFile;
  65.  
  66. // The default jump time is 5000 ms
  67. protected long jumpTime = 5000;
  68.  
  69. @Override
  70. public void init(ServletConfig config) throws ServletException {
  71. super.init(config);
  72. try {
  73. if (config.getInitParameter(CONFIG_JUMP_TIME) != null) {
  74. jumpTime = Long.parseLong(config.getInitParameter(CONFIG_JUMP_TIME));
  75. }
  76. promptAudioFile = URI.create(config.getInitParameter(CONFIG_AUDIO_FILE));
  77. // create the Media Session Factory
  78. msControlFactory = DriverManager.getDrivers().next().getFactory(null);
  79. }
  80. catch (Exception e) {
  81. throw new ServletException(e);
  82. }
  83. networkConnectionListener = new MyRtpPortsListener();
  84. playerListener = new MyPlayerListener();
  85. sigDetListener = new MySigDetListener();
  86. }
  87.  
  88. @Override
  89. public void doInvite(final SipServletRequest req) throws ServletException, IOException {
  90. NetworkConnection conn = null;
  91.  
  92. SipSession sipSession = req.getSession();
  93. if (req.isInitial()) {
  94. // New Call
  95. try {
  96.  
  97. // Create new media session and store in SipSession
  98. MediaSession mediaSession = msControlFactory.createMediaSession();
  99. sipSession.setAttribute("MEDIA_SESSION", mediaSession);
  100. mediaSession.setAttribute("SIP_SESSION", sipSession);
  101.  
  102. // Create a new NetworkConnection and store in SipSession
  103. conn = mediaSession.createNetworkConnection(NetworkConnection.BASIC);
  104. // Set this servlet class as listener of the RTP ports manager
  105. conn.getSdpPortManager().addListener(networkConnectionListener);
  106. sipSession.setAttribute("NETWORK_CONNECTION", conn);
  107. }
  108. catch (MediaConfigException e) {
  109. req.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR).send();
  110. return;
  111. }
  112. catch (MsControlException e) {
  113. // Probably out of resources, or other media server problem. send 503
  114. req.createResponse(SipServletResponse.SC_SERVICE_UNAVAILABLE).send();
  115. return;
  116. }
  117. }
  118. else {
  119. // Existing call. This is an re-INVITE
  120. // Get NetworkConnection from SipSession
  121. conn = (NetworkConnection) sipSession.getAttribute("NETWORK_CONNECTION");
  122. }
  123.  
  124. // set SDP of peer UA to NetworkConnection ()
  125. try {
  126. // Store INVITE so it can be responded to later
  127. sipSession.setAttribute("UNANSWERED_INVITE", req);
  128.  
  129. // set state
  130. setState(sipSession, WAITING_FOR_MEDIA_SERVER);
  131.  
  132. // assume here that the only possible body is an SDP
  133. // may be null, indicating an INVITE w/o SDP
  134. byte[] sdpOffer = req.getRawContent();
  135. if (sdpOffer == null)
  136. conn.getSdpPortManager().generateSdpOffer();
  137. else
  138. conn.getSdpPortManager().processSdpOffer(sdpOffer);
  139.  
  140. }
  141. catch (SdpException e) {
  142. req.createResponse(SipServletResponse.SC_NOT_ACCEPTABLE_HERE).send();
  143. return;
  144. }
  145. catch (SdpPortManagerException e) {
  146. // Unknown exception, just send 503
  147. req.createResponse(SipServletResponse.SC_SERVICE_UNAVAILABLE).send();
  148. return;
  149. }
  150. catch (MsControlException e) {
  151. // Unknown exception, just send 503
  152. req.createResponse(SipServletResponse.SC_SERVICE_UNAVAILABLE).send();
  153. return;
  154. }
  155. }
  156.  
  157. @Override
  158. protected void doAck(SipServletRequest req) throws ServletException, IOException {
  159. SipSession sipSession = req.getSession();
  160. // Get NetworkConnection from SipSession
  161. NetworkConnection conn = (NetworkConnection) sipSession.getAttribute("NETWORK_CONNECTION");
  162.  
  163. // Check if ACK contains an SDP (assume here that the only possible body is
  164. // an SDP)
  165. byte[] remoteSdp = req.getRawContent();
  166. if (remoteSdp != null) {
  167. // ACK contains an SDP, should be an answer.
  168. // set SDP of peer UA.
  169. try {
  170. // set state
  171. setState(sipSession, WAITING_FOR_MEDIA_SERVER_2);
  172.  
  173. conn.getSdpPortManager().processSdpAnswer( // The local (media server)
  174. // side has already been set
  175. remoteSdp); // remote side is the peer UA
  176. }
  177. catch (Exception e) {
  178. // Not much to do. Hope for the best and carry on.
  179. log(e.toString());
  180. }
  181. }
  182.  
  183. if (compareState(sipSession, WAITING_FOR_ACK)) {
  184. // Play file now
  185. runDialog(sipSession);
  186. }
  187. }
  188.  
  189. @Override
  190. protected void doCancel(SipServletRequest req) throws ServletException, IOException {
  191. MediaSession mediaSession = (MediaSession) req.getSession().getAttribute("MEDIA_SESSION");
  192. mediaSession.release();
  193. req.getApplicationSession().invalidate();
  194. }
  195.  
  196. @Override
  197. public void doBye(final SipServletRequest req) throws ServletException, IOException {
  198. MediaSession mediaSession = (MediaSession) req.getSession().getAttribute("MEDIA_SESSION");
  199. mediaSession.release();
  200. req.createResponse(SipServletResponse.SC_OK).send();
  201. req.getApplicationSession().invalidate();
  202. }
  203.  
  204. private boolean compareState(SipSession sipSession, String state) {
  205. return state.equals(sipSession.getAttribute("STATE"));
  206. }
  207.  
  208. protected void setState(SipSession sipSession, String state) {
  209. sipSession.setAttribute("STATE", state);
  210. }
  211.  
  212. private class MyRtpPortsListener implements MediaEventListener<SdpPortManagerEvent> {
  213. public void onEvent(SdpPortManagerEvent event) {
  214. MediaSession mediaSession = event.getSource().getMediaSession();
  215.  
  216. SipSession sipSession = (SipSession) mediaSession.getAttribute("SIP_SESSION");
  217.  
  218. SipServletRequest inv = (SipServletRequest) sipSession.getAttribute("UNANSWERED_INVITE");
  219. sipSession.removeAttribute("UNANSWERED_INVITE");
  220.  
  221. try {
  222. if (event.isSuccessful()) {
  223. if (compareState(sipSession, WAITING_FOR_MEDIA_SERVER)) {
  224. // Return an SDP attached to a 200 OK message
  225. SipServletResponse resp = inv.createResponse(SipServletResponse.SC_OK);
  226. // Get SDP from NetworkConnection
  227. byte[] sdp = event.getMediaServerSdp();
  228. resp.setContent(sdp, "application/sdp");
  229. // Send 200 OK
  230. resp.send();
  231. setState(sipSession, WAITING_FOR_ACK);
  232. }
  233. else if (compareState(sipSession, WAITING_FOR_MEDIA_SERVER_2)) {
  234. // The media server has updated the remote SDP received with the
  235. // ACK.
  236. // The INVITE is complete, we are ready to play.
  237. runDialog(sipSession);
  238. }
  239. }
  240. else {
  241. if (SdpPortManagerEvent.SDP_NOT_ACCEPTABLE.equals(event.getError())) {
  242. // Send 488 error response to INVITE
  243. inv.createResponse(SipServletResponse.SC_NOT_ACCEPTABLE_HERE).send();
  244. }
  245. else if (SdpPortManagerEvent.RESOURCE_UNAVAILABLE.equals(event.getError())) {
  246. // Send 486 error response to INVITE
  247. inv.createResponse(SipServletResponse.SC_BUSY_HERE).send();
  248. }
  249. else {
  250. // Some unknown error. Send 500 error response to INVITE
  251. inv.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR).send();
  252. }
  253. // Clean up media session
  254. sipSession.removeAttribute("MEDIA_SESSION");
  255. mediaSession.release();
  256. }
  257. }
  258. catch (Exception e) {
  259. e.printStackTrace();
  260. // Clean up
  261. sipSession.getApplicationSession().invalidate();
  262. mediaSession.release();
  263. }
  264. }
  265. }
  266.  
  267. /**
  268. * Start IVR.
  269. *
  270. * @param sipSession
  271. */
  272. protected void runDialog(SipSession sipSession) {
  273. try {
  274. MediaGroup mg = null;
  275. mg = (MediaGroup) sipSession.getAttribute("MEDIAGROUP");
  276. if (mg == null) {
  277. // Create a MediaGroup
  278. MediaSession ms = (MediaSession) sipSession.getAttribute("MEDIA_SESSION");
  279. mg = ms.createMediaGroup(MediaGroup.PLAYER_SIGNALDETECTOR);
  280. // Save reference for future use
  281. sipSession.setAttribute("MEDIAGROUP", mg);
  282. // Attach a listener to the SignalDetector
  283. mg.getSignalDetector().addListener(sigDetListener);
  284. // Join it to the NetworkConnection
  285. mg.join(Direction.DUPLEX, (NetworkConnection) sipSession.getAttribute("NETWORK_CONNECTION"));
  286. }
  287.  
  288. Parameters params = mg.createParameters();
  289. params.put(SignalDetector.PATTERN[0], "1");
  290. // The prompt to play
  291. URI prompt = createTTSResource("Welcome to the player sample application. Press 1 to play the audio file.");
  292. params.put(SignalDetector.PROMPT, prompt);
  293.  
  294. // start the collect operation
  295. // RTC indicates that any DTMF typed when the prompt is playing, will stop
  296. // the prompt
  297. mg.getSignalDetector().receiveSignals(-1, new Parameter[] {SignalDetector.PATTERN[0]},
  298. new RTC[] {MediaGroup.SIGDET_STOPPLAY}, params);
  299. setState(sipSession, DIALOG);
  300. }
  301. catch (Exception e) {
  302. // Clean up media session
  303. MediaSession mediaSession = (MediaSession) sipSession.getAttribute("MEDIA_SESSION");
  304. terminate(sipSession, mediaSession);
  305. }
  306. }
  307.  
  308. class MyPlayerListener implements MediaEventListener<PlayerEvent> {
  309.  
  310. public void onEvent(PlayerEvent event) {
  311. MediaSession mediaSession = event.getSource().getMediaSession();
  312. SipSession sipSession = (SipSession) mediaSession.getAttribute("SIP_SESSION");
  313. if (event.isSuccessful()) {
  314. final EventType type = event.getEventType();
  315. if (type.equals(PlayerEvent.PAUSED)) {
  316. log("Play is paused with: " + event);
  317. }
  318. else if (type.equals(PlayerEvent.RESUMED)) {
  319. log("Play is resumed with: " + event);
  320. }
  321. else {
  322. log("Play terminated with: " + event);
  323. // Release the call and terminate
  324. terminate(sipSession, mediaSession);
  325. }
  326. }
  327. else {
  328. log("Play terminated with: " + event);
  329. // Release the call and terminate
  330. terminate(sipSession, mediaSession);
  331. }
  332. }
  333. }
  334.  
  335. class MySigDetListener implements MediaEventListener<SignalDetectorEvent> {
  336.  
  337. public void onEvent(SignalDetectorEvent event) {
  338. log("SignalDetector terminated with: " + event);
  339. MediaSession mediaSession = event.getSource().getMediaSession();
  340. SipSession sipSession = (SipSession) mediaSession.getAttribute("SIP_SESSION");
  341.  
  342. if (event.isSuccessful()) {
  343. try {
  344. MediaGroup mg = (MediaGroup) event.getSource().getContainer();
  345. Parameters params = mg.createParameters();
  346. // define grammar
  347. params.put(SignalDetector.PATTERN[2], "2");
  348. params.put(SignalDetector.PATTERN[3], "3");
  349. params.put(SignalDetector.PATTERN[4], "4");
  350. params.put(SignalDetector.PATTERN[5], "5");
  351. // define JUMP_TIME
  352. params.put(Player.JUMP_TIME, jumpTime);
  353.  
  354. // press 2 to pause
  355. RTC pauseRTC = new RTC(SignalDetector.PATTERN_MATCH[2], Player.PAUSE);
  356. // press 3 to rewind
  357. RTC rewindRTC = new RTC(SignalDetector.PATTERN_MATCH[3], Player.JUMP_BACKWARD);
  358. // press 4 to fastforward
  359. RTC forwardRTC = new RTC(SignalDetector.PATTERN_MATCH[4], Player.JUMP_FORWARD);
  360. // press 5 to resume
  361. RTC resumeRTC = new RTC(SignalDetector.PATTERN_MATCH[5], Player.RESUME);
  362.  
  363. // Attach a listener to the Player
  364. mg.getPlayer().addListener(playerListener);
  365. // start playing the audio file
  366. mg.getPlayer().play(promptAudioFile, new RTC[] {pauseRTC, rewindRTC, forwardRTC, resumeRTC}, params);
  367. }
  368. catch (Exception e) {
  369. // Clean up media session
  370. terminate(sipSession, mediaSession);
  371. }
  372. }
  373. else {
  374. // Clean up media session
  375. terminate(sipSession, mediaSession);
  376. }
  377. }
  378. }
  379.  
  380. protected void terminate(SipSession sipSession, MediaSession mediaSession) {
  381. SipServletRequest bye = sipSession.createRequest("BYE");
  382. try {
  383. bye.send();
  384. // Clean up media session
  385. mediaSession.release();
  386. sipSession.removeAttribute("MEDIA_SESSION");
  387. setState(sipSession, BYE_SENT);
  388. }
  389. catch (Exception e1) {
  390. log("Terminating: Cannot send BYE: " + e1);
  391. }
  392. }
  393.  
  394. // create ssml uri used for TTS.
  395. private URI createTTSResource(final String text) throws UnsupportedEncodingException {
  396. return java.net.URI.create("data:"
  397. + URLEncoder.encode("application/ssml+xml," + "<?xml version=\"1.0\"?>" + "<speak>" + "<voice>" + text
  398. + "</voice>" + "</speak>", "UTF-8"));
  399. }
  400. }
Add Comment
Please, Sign In to add comment