001 /*
002 *
003 * $Revision: 15022 $ $Date: 2009-03-26 14:53:00 +0100 (Thu, 26 Mar 2009) $
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.realhelix;
025
026 import java.io.IOException;
027 import java.io.OutputStream;
028 import java.net.URLConnection;
029 import java.util.StringTokenizer;
030
031 import org.apache.log4j.Logger;
032 import org.mycore.common.MCRConfiguration;
033 import org.mycore.common.MCRPersistenceException;
034 import org.mycore.datamodel.ifs.MCRAudioVideoExtender;
035 import org.mycore.datamodel.ifs.MCRFileReader;
036
037 /**
038 * This class implements the AudioVideoExtender functions for Real Server 8 and
039 * Helix Universal Streaming Server 9 instances. It reads technical metadata
040 * about stored assets by parsing the Real Server's "View Source" responses and
041 * gets a player starter file using the "/ramgen/" mount point. The parameters
042 * can be configured in mycore.properties:
043 *
044 * <code>
045 * MCR.IFS.AVExtender.<StoreID>.RamGenBaseURL URL of ramgen mount point
046 * MCR.IFS.AVExtender.<StoreID>.AsxGenBaseURL URL of asxgen mount point
047 * MCR.IFS.AVExtender.<StoreID>.ViewSourceBaseURL URL of view source function
048 * MCR.IFS.AVExtender.<StoreID>.RealPlayerURL Download URL for RealOne Player
049 * MCR.IFS.AVExtender.<StoreID>.MediaPlayerURL Download URL for Microsoft Player
050 * </code>
051 *
052 * @author Frank Lützenkirchen
053 * @version $Revision: 15022 $ $Date: 2009-03-26 14:53:00 +0100 (Thu, 26 Mar 2009) $
054 */
055 public class MCRAVExtRealHelix extends MCRAudioVideoExtender {
056
057 /** The logger */
058 private final static Logger LOGGER = Logger.getLogger(MCRAVExtRealHelix.class);
059
060 public MCRAVExtRealHelix() {
061 }
062
063 public void init(MCRFileReader file) throws MCRPersistenceException {
064 super.init(file);
065
066 MCRConfiguration config = MCRConfiguration.instance();
067 String prefix = "MCR.IFS.AVExtender." + file.getStoreID() + ".";
068
069 baseMetadata = config.getString(prefix + "ViewSourceBaseURL");
070
071 try {
072 String data = getMetadata(baseMetadata + file.getStorageID());
073
074 String sSize = getBetween("File Size:</strong>", "Bytes", data, "0");
075 String sBitRate = getBetween("Bit Rate:</strong>", "Kbps", data, "0.0");
076 String sFrameRate = getBetween("Frame Rate: </strong>", "fps", data, "0.0");
077 String sDuration = getBetween("Duration:</strong>", "<br>", data, "0:0.0");
078 String sType = getBetween("Stream:</strong>", "<br>", data, "");
079
080 bitRate = Math.round(1024 * Float.valueOf(sBitRate).floatValue());
081
082 StringTokenizer st1 = new StringTokenizer(sFrameRate, " ,");
083
084 while (st1.hasMoreTokens()) {
085 double value = Double.valueOf(st1.nextToken()).doubleValue();
086 frameRate = Math.max(frameRate, value);
087 }
088
089 mediaType = (frameRate > 0);
090
091 StringTokenizer st2 = new StringTokenizer(sDuration, ":.");
092 durationMinutes = Integer.parseInt(st2.nextToken());
093 durationSeconds = Integer.parseInt(st2.nextToken());
094
095 if (Integer.parseInt(st2.nextToken()) > 499) {
096 durationSeconds += 1;
097
098 if (durationSeconds > 59) {
099 durationMinutes += 1;
100 durationSeconds = 0;
101 }
102 }
103
104 StringTokenizer st3 = new StringTokenizer(sSize, ",");
105 StringBuffer sb = new StringBuffer();
106
107 while (st3.hasMoreTokens())
108 sb.append(st3.nextToken());
109
110 size = Long.parseLong(sb.toString());
111
112 durationHours = (durationMinutes / 60);
113 durationMinutes = durationMinutes - (durationHours * 60);
114
115 if (sType.indexOf("MPEG Layer 3") >= 0) {
116 contentTypeID = "mp3";
117 mediaType = AUDIO;
118 } else if (sType.indexOf("MPEG") >= 0) {
119 contentTypeID = "mpegvid";
120 mediaType = VIDEO;
121 } else if (sType.indexOf("RealVideo") >= 0) {
122 contentTypeID = "realvid";
123 } else if (sType.indexOf("RealAudio") >= 0) {
124 contentTypeID = "realaud";
125 } else if (sType.indexOf("Wave File") >= 0) {
126 contentTypeID = "wav";
127 mediaType = AUDIO;
128 } else // should be one of "wma" "wmv" "asf"
129 {
130 contentTypeID = file.getContentTypeID();
131
132 if (contentTypeID.equals("wma")) {
133 mediaType = AUDIO;
134 } else {
135 mediaType = VIDEO;
136 }
137 }
138
139 if (" wma wmv asf asx ".indexOf(" " + contentTypeID + " ") != -1) {
140 basePlayerStarter = config.getString(prefix + "AsxGenBaseURL");
141 playerDownloadURL = config.getString(prefix + "MediaPlayerURL");
142 } else {
143 basePlayerStarter = config.getString(prefix + "RamGenBaseURL");
144 playerDownloadURL = config.getString(prefix + "RealPlayerURL");
145 }
146
147 URLConnection con = getConnection(basePlayerStarter + file.getStorageID());
148 playerStarterCT = con.getContentType();
149 } catch (Exception exc) {
150 String msg = "Error parsing metadata from Real Server ViewSource: " + file.getStorageID();
151 LOGGER.warn(msg, exc);
152 }
153 }
154
155 public void getPlayerStarterTo(OutputStream out, String startPos, String stopPos) throws MCRPersistenceException {
156 if (basePlayerStarter == null || basePlayerStarter.length() < 8) {
157 String msg = "Temporary Failure. Could not start streaming of file: " + file.getPath();
158 throw new MCRPersistenceException(msg);
159 }
160
161 try {
162 StringBuffer cgi = new StringBuffer(basePlayerStarter);
163 cgi.append(file.getStorageID());
164
165 if ((startPos != null) || (stopPos != null)) {
166 cgi.append("?");
167 }
168
169 if (startPos != null) {
170 cgi.append("start=").append(startPos);
171 }
172
173 if ((startPos != null) && (stopPos != null)) {
174 cgi.append("&");
175 }
176
177 if (stopPos != null) {
178 cgi.append("end=").append(stopPos);
179 }
180
181 URLConnection connection = getConnection(cgi.toString());
182 forwardData(connection, out);
183 } catch (IOException exc) {
184 String msg = "Could not send player starter file";
185 throw new MCRPersistenceException(msg, exc);
186 }
187 }
188 }