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.io.File;
020import java.io.IOException;
021import java.util.ArrayList;
022import java.util.List;
023import java.util.logging.Level;
024import java.util.logging.Logger;
025
026import org.jivesoftware.smackx.jingleold.JingleSession;
027import org.jivesoftware.smackx.jingleold.media.JingleMediaManager;
028import org.jivesoftware.smackx.jingleold.media.JingleMediaSession;
029import org.jivesoftware.smackx.jingleold.media.PayloadType;
030import org.jivesoftware.smackx.jingleold.mediaimpl.JMFInit;
031import org.jivesoftware.smackx.jingleold.nat.JingleTransportManager;
032import org.jivesoftware.smackx.jingleold.nat.TransportCandidate;
033
034/**
035 * Implements a jingleMediaManager using JMF based API.
036 * It supports GSM and G723 codices.
037 * <i>This API only currently works on windows and Mac.</i>
038 *
039 * @author Thiago Camargo
040 */
041public class JmfMediaManager extends JingleMediaManager {
042
043    private static final Logger LOGGER = Logger.getLogger(JmfMediaManager.class.getName());
044
045    public static final String MEDIA_NAME = "JMF";
046
047
048    private List<PayloadType> payloads = new ArrayList<>();
049    private String mediaLocator = null;
050
051    /**
052     * Creates a Media Manager instance.
053     */
054    public JmfMediaManager(JingleTransportManager transportManager) {
055        super(transportManager);
056        setupPayloads();
057    }
058
059    /**
060     * Creates a Media Manager instance.
061     *
062     * @param mediaLocator Media Locator
063     */
064    public JmfMediaManager(String mediaLocator, JingleTransportManager transportManager) {
065        super(transportManager);
066        this.mediaLocator = mediaLocator;
067        setupPayloads();
068    }
069
070    /**
071     * Returns a new jingleMediaSession.
072     *
073     * @param payloadType payloadType
074     * @param remote      remote Candidate
075     * @param local       local Candidate
076     * @return JingleMediaSession
077     */
078    @Override
079    public JingleMediaSession createMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
080        return new AudioMediaSession(payloadType, remote, local, mediaLocator, jingleSession);
081    }
082
083    /**
084     * Setup API supported Payloads
085     */
086    private void setupPayloads() {
087        payloads.add(new PayloadType.Audio(3, "gsm"));
088        payloads.add(new PayloadType.Audio(4, "g723"));
089        payloads.add(new PayloadType.Audio(0, "PCMU", 16000));
090    }
091
092    /**
093     * Return all supported Payloads for this Manager.
094     *
095     * @return The Payload List
096     */
097    @Override
098    public List<PayloadType> getPayloads() {
099        return payloads;
100    }
101
102    /**
103     * Return the media locator or null if not defined.
104     *
105     * @return media locator
106     */
107    public String getMediaLocator() {
108        return mediaLocator;
109    }
110
111    /**
112     * Set the media locator.
113     *
114     * @param mediaLocator media locator or null to use default
115     */
116    public void setMediaLocator(String mediaLocator) {
117        this.mediaLocator = mediaLocator;
118    }
119
120    /**
121     * Runs JMFInit the first time the application is started so that capture
122     * devices are properly detected and initialized by JMF.
123     */
124    public static void setupJMF() {
125        // .jmf is the place where we store the jmf.properties file used
126        // by JMF. if the directory does not exist or it does not contain
127        // a jmf.properties file. or if the jmf.properties file has 0 length
128        // then this is the first time we're running and should continue to
129        // with JMFInit
130        String homeDir = System.getProperty("user.home");
131        File jmfDir = new File(homeDir, ".jmf");
132        String classpath = System.getProperty("java.class.path");
133        classpath += System.getProperty("path.separator")
134                + jmfDir.getAbsolutePath();
135        System.setProperty("java.class.path", classpath);
136
137        if (!jmfDir.exists())
138            jmfDir.mkdir();
139
140        File jmfProperties = new File(jmfDir, "jmf.properties");
141
142        if (!jmfProperties.exists()) {
143            try {
144                jmfProperties.createNewFile();
145            }
146            catch (IOException ex) {
147                LOGGER.log(Level.FINE, "Failed to create jmf.properties", ex);
148            }
149        }
150
151        // if we're running on linux checkout that libjmutil.so is where it
152        // should be and put it there.
153        runLinuxPreInstall();
154
155        // if (jmfProperties.length() == 0) {
156        new JMFInit(null, false);
157        // }
158
159    }
160
161    private static void runLinuxPreInstall() {
162        // @TODO Implement Linux Pre-Install
163    }
164
165    @Override
166    public  String getName() {
167        return MEDIA_NAME;
168    }
169}