1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.opencastproject.mediapackage.track;
24
25 import org.opencastproject.mediapackage.MediaPackageSerializer;
26 import org.opencastproject.mediapackage.VideoStream;
27
28 import org.apache.commons.lang3.StringUtils;
29 import org.w3c.dom.Document;
30 import org.w3c.dom.Element;
31 import org.w3c.dom.Node;
32
33 import java.util.UUID;
34
35 import javax.xml.bind.annotation.XmlAccessType;
36 import javax.xml.bind.annotation.XmlAccessorType;
37 import javax.xml.bind.annotation.XmlAttribute;
38 import javax.xml.bind.annotation.XmlElement;
39 import javax.xml.bind.annotation.XmlType;
40 import javax.xml.xpath.XPath;
41 import javax.xml.xpath.XPathConstants;
42 import javax.xml.xpath.XPathException;
43
44
45
46
47 @XmlAccessorType(XmlAccessType.NONE)
48 @XmlType(name = "video", namespace = "http://mediapackage.opencastproject.org")
49 public class VideoStreamImpl extends AbstractStreamImpl implements VideoStream {
50
51 @XmlElement(name = "bitrate")
52 protected Float bitRate;
53
54 @XmlElement(name = "framerate")
55 protected Float frameRate;
56
57 @XmlElement(name = "resolution")
58 protected String resolution;
59
60 protected Integer frameWidth;
61 protected Integer frameHeight;
62
63 @XmlElement(name = "scantype")
64 protected Scan scanType = null;
65
66 @XmlType(name = "scantype")
67 static class Scan {
68 @XmlAttribute(name = "type")
69 protected ScanType type;
70 @XmlAttribute(name = "order")
71 protected ScanOrder order;
72
73 @Override
74 public String toString() {
75 return type.toString();
76 }
77 }
78
79 public VideoStreamImpl() {
80 this(UUID.randomUUID().toString());
81 }
82
83 public VideoStreamImpl(String identifier) {
84 super(identifier);
85 }
86
87
88
89
90
91
92
93
94 public static VideoStreamImpl fromManifest(String streamIdHint, Node node, XPath xpath) throws IllegalStateException,
95 XPathException {
96
97 String sid = (String) xpath.evaluate("@id", node, XPathConstants.STRING);
98 if (StringUtils.isEmpty(sid)) {
99 sid = streamIdHint;
100 }
101 VideoStreamImpl vs = new VideoStreamImpl(sid);
102 partialFromManifest(vs, node, xpath);
103
104
105 try {
106 String strBitrate = (String) xpath.evaluate("bitrate/text()", node, XPathConstants.STRING);
107 if (StringUtils.isNotEmpty(strBitrate))
108 vs.bitRate = Float.valueOf(strBitrate.trim());
109 } catch (NumberFormatException e) {
110 throw new IllegalStateException("Bit rate was malformatted: " + e.getMessage());
111 }
112
113
114 try {
115 String strFrameRate = (String) xpath.evaluate("framerate/text()", node, XPathConstants.STRING);
116 if (StringUtils.isNotEmpty(strFrameRate))
117 vs.frameRate = Float.valueOf(strFrameRate.trim());
118 } catch (NumberFormatException e) {
119 throw new IllegalStateException("Frame rate was malformatted: " + e.getMessage());
120 }
121
122
123 String res = (String) xpath.evaluate("resolution/text()", node, XPathConstants.STRING);
124 if (StringUtils.isNotEmpty(res)) {
125 vs.resolution = res;
126 }
127
128
129 String scanType = (String) xpath.evaluate("scantype/@type", node, XPathConstants.STRING);
130 if (StringUtils.isNotEmpty(scanType)) {
131 if (vs.scanType == null)
132 vs.scanType = new Scan();
133 vs.scanType.type = ScanType.fromString(scanType);
134 }
135
136 String scanOrder = (String) xpath.evaluate("interlacing/@order", node, XPathConstants.STRING);
137 if (StringUtils.isNotEmpty(scanOrder)) {
138 if (vs.scanType == null)
139 vs.scanType = new Scan();
140 vs.scanType.order = ScanOrder.fromString(scanOrder);
141 }
142
143 return vs;
144 }
145
146
147
148
149
150 @Override
151 public Node toManifest(Document document, MediaPackageSerializer serializer) {
152 Element node = document.createElement("video");
153 addCommonManifestElements(node, document, serializer);
154
155
156 Element resolutionNode = document.createElement("resolution");
157 resolutionNode.appendChild(document.createTextNode(resolution));
158 node.appendChild(resolutionNode);
159
160
161 if (scanType != null) {
162 Element interlacingNode = document.createElement("scantype");
163 interlacingNode.setAttribute("type", scanType.toString());
164 if (scanType.order != null)
165 interlacingNode.setAttribute("order", scanType.order.toString());
166 node.appendChild(interlacingNode);
167 }
168
169
170 if (bitRate != null) {
171 Element bitrateNode = document.createElement("bitrate");
172 bitrateNode.appendChild(document.createTextNode(bitRate.toString()));
173 node.appendChild(bitrateNode);
174 }
175
176
177 if (frameRate != null) {
178 Element framerateNode = document.createElement("framerate");
179 framerateNode.appendChild(document.createTextNode(frameRate.toString()));
180 node.appendChild(framerateNode);
181 }
182
183 return node;
184 }
185
186 @Override
187 public Float getBitRate() {
188 return bitRate;
189 }
190
191 @Override
192 public Float getFrameRate() {
193 return frameRate;
194 }
195
196 @Override
197 public Integer getFrameWidth() {
198 try {
199 String[] s = resolution.trim().split("x");
200 if (s.length != 2)
201 throw new IllegalStateException("video size must be of the form <hsize>x<vsize>, found " + resolution);
202 return Integer.valueOf(s[0].trim());
203 } catch (NumberFormatException e) {
204 throw new IllegalStateException("Resolution was malformatted: " + e.getMessage());
205 }
206 }
207
208 @Override
209 public Integer getFrameHeight() {
210 try {
211 String[] s = resolution.trim().split("x");
212 if (s.length != 2)
213 throw new IllegalStateException("video size must be of the form <hsize>x<vsize>, found " + resolution);
214 return Integer.valueOf(s[1].trim());
215 } catch (NumberFormatException e) {
216 throw new IllegalStateException("Resolution was malformatted: " + e.getMessage());
217 }
218 }
219
220 @Override
221 public ScanType getScanType() {
222 return scanType != null ? scanType.type : null;
223 }
224
225 @Override
226 public ScanOrder getScanOrder() {
227 return scanType != null ? scanType.order : null;
228 }
229
230
231
232 public void setBitRate(Float bitRate) {
233 this.bitRate = bitRate;
234 }
235
236 public void setFrameRate(Float frameRate) {
237 this.frameRate = frameRate;
238 }
239
240 public void setFrameWidth(Integer frameWidth) {
241 this.frameWidth = frameWidth;
242 if (frameWidth != null && frameHeight != null)
243 updateResolution();
244 }
245
246 public void setFrameHeight(Integer frameHeight) {
247 this.frameHeight = frameHeight;
248 if (frameWidth != null && frameHeight != null)
249 updateResolution();
250 }
251
252 private void updateResolution() {
253 resolution = frameWidth.toString() + "x" + frameHeight.toString();
254 }
255
256 public void setScanType(ScanType scanType) {
257 if (scanType == null)
258 return;
259 if (this.scanType == null)
260 this.scanType = new Scan();
261 this.scanType.type = scanType;
262 }
263
264 public void setScanOrder(ScanOrder scanOrder) {
265 if (scanOrder == null)
266 return;
267 if (this.scanType == null)
268 this.scanType = new Scan();
269 this.scanType.order = scanOrder;
270 }
271 }