001    /*
002     * 
003     * $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
004     *
005     * This file is part of ***  M y C o R e  ***
006     * See http://www.mycore.de/ for details.
007     *
008     * This program is free software; you can use it, redistribute it
009     * and / or modify it under the terms of the GNU General Public License
010     * (GPL) as published by the Free Software Foundation; either version 2
011     * of the License or (at your option) any later version.
012     *
013     * This program is distributed in the hope that it will be useful, but
014     * WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program, in a file called gpl.txt or license.txt.
020     * If not, write to the Free Software Foundation Inc.,
021     * 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA
022     */
023    
024    package org.mycore.backend.videocharger;
025    
026    import java.io.IOException;
027    import java.io.OutputStream;
028    import java.io.UnsupportedEncodingException;
029    import java.net.URLConnection;
030    import java.net.URLEncoder;
031    import java.util.StringTokenizer;
032    
033    import org.apache.log4j.Logger;
034    import org.mycore.common.MCRConfiguration;
035    import org.mycore.common.MCRPersistenceException;
036    import org.mycore.datamodel.ifs.MCRAudioVideoExtender;
037    import org.mycore.datamodel.ifs.MCRFileReader;
038    
039    /**
040     * This class implements the AudioVideoExtender functions for IBM VideoCharger
041     * 7.1 and 8.1 instances. It reads technical metadata about stored assets by
042     * parsing the vslist cgi responses and gets a player starter file using the
043     * iscpfsel cgi. The parameters can be configured in mycore.properties:
044     * 
045     * <code>
046     MCR.IFS.AVExtender.<StoreID>.VSListURL    URL of vslist cgi
047     MCR.IFS.AVExtender.<StoreID>.ISCPFSelURL  URL of iscpfsel cgi
048     MCR.IFS.AVExtender.<StoreID>.PlayerURL    Download URL for VideoCharger Player
049     * </code>
050     * 
051     * This class also provides a method to list all assets in a VideoCharger store.
052     * 
053     * @author Frank Lützenkirchen
054     * @version $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
055     */
056    public class MCRAVExtVideoCharger extends MCRAudioVideoExtender {
057        /** The logger */
058        private final static Logger LOGGER = Logger.getLogger( MCRAVExtVideoCharger.class );
059    
060        protected static String assetGroup;
061        protected static String encoding;
062        
063        public void readConfig(String storeID) {
064            String prefix = "MCR.IFS.AVExtender." + storeID + ".";
065    
066            MCRConfiguration CONFIG = MCRConfiguration.instance();
067            encoding = CONFIG.getString("MCR.Request.CharEncoding", "UTF-8"); 
068            baseMetadata = CONFIG.getString(prefix + "VSListURL");
069            playerDownloadURL = CONFIG.getString(prefix + "PlayerURL");
070            basePlayerStarter = CONFIG.getString(prefix + "ISCPFSelURL");
071    
072            assetGroup = CONFIG.getString("MCR.IFS.ContentStore." + storeID + ".AssetGroup", "AG" );
073            basePlayerStarter += "?VIDEOAG=" + assetGroup + "&VIDEOID=";
074            baseMetadata += "?" + assetGroup;
075        }
076    
077        public void init(MCRFileReader file) throws MCRPersistenceException {
078            super.init(file);
079    
080            readConfig(file.getStoreID());
081    
082            String assetID;
083    
084            try {
085                assetID = URLEncoder.encode(file.getStorageID(), encoding);
086            } catch (UnsupportedEncodingException e) {
087                throw new MCRPersistenceException("MCR.Request.CharEncoding property does not contain a valid encoding:", e);
088            }
089    
090            try {
091                String data1 = getMetadata(baseMetadata + "%20" + assetID);
092                String data2 = getMetadata(basePlayerStarter + assetID);
093    
094                URLConnection con = getConnection(basePlayerStarter + assetID);
095                playerStarterCT = con.getContentType();
096    
097                String sSize = getBetween("filesize64=", "\n", data2, "0,0");
098                String sBitRate = getBetween("bitRate=", "\n", data1, "0");
099                String sFrameRate = getBetween("frameRate=", "\n", data1, "0");
100                String sDuration = getBetween("duration=", "\n", data1, "0:0:0:0");
101                String sType = getBetween("type=", "\n", data1, "");
102    
103                bitRate = Integer.parseInt(sBitRate);
104                frameRate = Double.valueOf(sFrameRate).doubleValue();
105                mediaType = (frameRate > 0);
106    
107                StringTokenizer st1 = new StringTokenizer(sSize, ",");
108                long sizeHi = Long.parseLong(st1.nextToken());
109                long sizeLo = Long.parseLong(st1.nextToken());
110                size = (sizeHi << 32) + sizeLo;
111    
112                StringTokenizer st2 = new StringTokenizer(sDuration, ":");
113                durationHours = Integer.parseInt(st2.nextToken());
114                durationMinutes = Integer.parseInt(st2.nextToken());
115                durationSeconds = Integer.parseInt(st2.nextToken());
116    
117                if (sType.indexOf("MPEG1") >= 0) {
118                    if (frameRate > 0) {
119                        contentTypeID = "mpegvid";
120                    } else if (file.getExtension().toLowerCase().equals("mp3")) {
121                        contentTypeID = "mp3";
122                    } else {
123                        contentTypeID = "mpegaud";
124                    }
125                } else if (sType.indexOf("MPEG2") >= 0) {
126                    contentTypeID = "mpegvid2";
127                } else if (sType.indexOf("MOV") >= 0) {
128                    contentTypeID = "qtvid";
129                } else if (sType.indexOf("WAV") >= 0) {
130                    contentTypeID = "wav";
131                } else if (sType.indexOf("AVI") >= 0) {
132                    contentTypeID = "avi";
133                }
134            } catch (Exception exc) {
135                String msg = "Error parsing metadata from VideoCharger asset " + file.getStorageID();
136                LOGGER.warn( msg, exc );
137            }
138        }
139    
140        public void getPlayerStarterTo(OutputStream out, String startPos, String stopPos) throws MCRPersistenceException {
141            try {
142                StringBuffer cgi = new StringBuffer(basePlayerStarter);
143                cgi.append(URLEncoder.encode(file.getStorageID(), encoding));
144    
145                if (startPos != null) {
146                    cgi.append("&StartPos=").append(startPos);
147                }
148    
149                if (stopPos != null) {
150                    cgi.append("&StopPos=").append(stopPos);
151                }
152    
153                URLConnection connection = getConnection(cgi.toString());
154                forwardData(connection, out);
155            } catch (IOException exc) {
156                String msg = "Could not send VideoCharger player starter";
157                throw new MCRPersistenceException(msg, exc);
158            }
159        }
160    
161        /**
162         * Lists all assets that are stored in this VideoCharger store.
163         * 
164         * @return a String array containing all asset IDs
165         */
166        public String[] listAssets() throws MCRPersistenceException {
167            String vslist = getMetadata(baseMetadata);
168            StringTokenizer st = new StringTokenizer(vslist, "\n");
169            String[] list = new String[st.countTokens()];
170    
171            for (int i = 0; i < list.length; i++)
172                list[i] = st.nextToken();
173    
174            return list;
175        }
176    }