UNPKG

6.08 kBJavaScriptView Raw
1/*jslint node: true, nomen: true, esversion: 6 */
2"use strict";
3
4const matroska = require('matroska');
5const Path = require('path');
6
7const debug = require('debug')('upnpserver:contentHandlers:Matroska');
8const logger = require('../logger');
9
10const ContentHandler = require('./contentHandler');
11
12class Video_Matroska extends ContentHandler {
13
14 /**
15 *
16 */
17 get name() {
18 return "matroska";
19 }
20
21 /**
22 *
23 */
24 prepareMetas(contentInfos, context, callback) {
25
26 var contentURL = contentInfos.contentURL;
27
28 var d1 = 0;
29 if (debug.enabled) {
30 debug("prepareMetas", "Parse matroska", contentURL);
31 d1 = Date.now();
32 }
33
34 var parsing;
35
36 try {
37 parsing = true;
38
39 var source = new matroska.StreamFactorySource({
40 getStream(session, options, callback) {
41 // console.log("getstream", options);
42
43 debug("prepareMetas", "getStream session=", session, " options=", options);
44
45 contentURL.createReadStream(session, options, callback);
46 },
47 end(session, callback) {
48 debug("prepareMetas", "endStream session=", session);
49
50 contentURL.contentProvider.end(session, callback);
51 }
52 });
53
54 matroska.Decoder.parseInfoTagsAndAttachments(source, (error, document) => {
55
56 parsing = false;
57
58 d1 = Date.now() - d1;
59
60 debug("prepareMetas", "Matroska parsed [" , d1 , "ms] contentURL=" , contentURL, "error=", error);
61
62 // debug("Return ", attributes.contentURL, error, document);
63
64 if (error || !document) {
65 logger.error("Can not parse mkv " + contentURL, error);
66 return callback();
67 }
68
69 if (debug.enabled) {
70 debug(document.print());
71 }
72
73 var segment = document.firstSegment;
74 if (!segment) {
75 return callback();
76 }
77
78 var metas={};
79
80 var info = segment.info;
81 if (info) {
82 if (info.title) {
83 metas.title = info.title;
84 }
85 }
86
87 // console.log(contentURL + "=>" + document.print());
88
89 var tags = segment.tags;
90
91 var attachments = segment.attachments;
92 if (attachments && attachments.attachedFiles) {
93
94 var res=[{}];
95
96 attachments.attachedFiles.forEach((attachedFile) => {
97
98 var fileData = attachedFile.$$fileData;
99 if (!fileData) {
100 return;
101 }
102
103 var name = attachedFile.fileName;
104 var ret = /([^\.]*)\..*/.exec(name);
105 if (ret) {
106 name = ret[1];
107 }
108
109 var mimeType = attachedFile.fileMimeType;
110 var png = (mimeType === "image/png");
111
112 var r = {
113 contentHandlerKey : this.name,
114 key : attachedFile.fileUID,
115 mimeType : mimeType,
116 size : fileData.getDataSize()
117// mtime: stats.mtime.getTime()
118 };
119
120 debug("prepareMetas", "Attachment:", name, r);
121
122 switch (name) {
123 case 'cover':
124 case 'cover_land':
125 r.dlnaProfile = (png) ? "PNG_MED" : "JPEG_MED";
126 res.push(r);
127 break;
128
129 case 'small_cover':
130 case 'small_cover_land':
131 r.dlnaProfile = (png) ? "PNG_TN" : "JPEG_TN";
132 res.push(r);
133 break;
134 }
135 });
136
137 if (res.length>1) {
138 metas.res=res;
139 }
140 }
141
142 callback(null, metas);
143 });
144
145 } catch (x) {
146 if (parsing) {
147 logger.error("MKV: Parsing exception" + contentURL, x);
148
149 return callback();
150 }
151
152 throw x;
153 }
154 }
155
156 /**
157 *
158 */
159 processRequest(node, request, response, path, parameters, callback) {
160
161 var resKey = parseFloat(parameters[0]);
162
163 debug("processRequest", "Process request ", resKey);
164
165 if (isNaN(resKey)) {
166 var error=new Error("Invalid resKey parameter ("+resKey+")");
167 return callback(error, true);
168 }
169
170 var attributes = node.attributes;
171
172 var contentURL = node.contentURL;
173
174 var source = new matroska.StreamFactorySource({
175 getStream(session, options, callback) {
176 debug("processRequest", "getStream session=", session, "options=", options);
177
178 contentURL.createReadStream(session, options, callback);
179 },
180 end(session, callback) {
181 debug("processRequest", "endStream session=", session);
182
183 contentURL.contentProvider.end(session, callback);
184 }
185 });
186
187 matroska.Decoder.parseInfoTagsAndAttachments(source, (error, document) => {
188
189 if (error || !document) {
190 return callback(error);
191 }
192
193 var segment = document.firstSegment;
194 if (!segment) {
195 return callback(new Error("No segment"), true);
196 }
197 var attachments = segment.attachments;
198 if (!attachments) {
199 return callback(new Error("No attachments"), true);
200 }
201
202 var attachedFile = attachments.attachedFiles.find((a) => a.fileUID === resKey);
203
204 if (!attachedFile) {
205 return callback(new Error("Can not find resource '" + resKey + "'"), true);
206 }
207
208 var fileData = attachedFile.$$fileData;
209
210 var fileMimeType = attachedFile.fileMimeType;
211 if (fileMimeType) {
212 response.setHeader("Content-Type", fileMimeType);
213 }
214 response.setHeader("Content-Size", fileData.getDataSize());
215 if (node.contentTime) {
216 var mtime=new Date(node.contentTime);
217 response.setHeader("Last-Modified", mtime.toUTCString());
218 }
219
220 fileData.getDataStream((error, stream) => {
221 if (error) {
222 return callback(error, true);
223 }
224
225 stream.pipe(response);
226
227 stream.on('end', () => callback(null, true));
228 });
229 });
230 }
231}
232
233module.exports = Video_Matroska;