Skip to content

Commit a282075

Browse files
fix: fetch overlay video creates correct transformation
1 parent 242ac45 commit a282075

File tree

6 files changed

+313
-127
lines changed

6 files changed

+313
-127
lines changed

lib-es5/utils/encoding/smart_escape.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
"use strict";
22

33
// Based on CGI::unescape. In addition does not escape / :
4-
// smart_escape = (string)->
5-
// encodeURIComponent(string).replace(/%3A/g, ":").replace(/%2F/g, "/")
4+
// smart_escape = (string) => encodeURIComponent(string).replace(/%3A/g, ":").replace(/%2F/g, "/")
65
function smart_escape(string) {
76
var unsafe = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : /([^a-zA-Z0-9_.\-\/:]+)/g;
87

lib-es5/utils/index.js

Lines changed: 109 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ function textStyle(layer) {
131131
});
132132

133133
if (layer.hasOwnProperty("font_size" || "font_family") || !isEmpty(keywords)) {
134-
if (!layer.font_size) throw `Must supply font_size for text in overlay/underlay`;
135-
if (!layer.font_family) throw `Must supply font_family for text in overlay/underlay`;
134+
if (!layer.font_size) throw new Error('Must supply font_size for text in overlay/underlay');
135+
if (!layer.font_family) throw new Error('Must supply font_family for text in overlay/underlay');
136136
keywords.unshift(layer.font_size);
137137
keywords.unshift(layer.font_family);
138138
style = compact(keywords).join("_");
@@ -222,71 +222,117 @@ function process_if(ifValue) {
222222
* @return {string} layer transformation string
223223
*/
224224
function process_layer(layer) {
225-
var result = '';
226-
if (isPlainObject(layer)) {
227-
if (layer.resource_type === "fetch" || layer.url != null) {
228-
result = `fetch:${base64EncodeURL(layer.url)}`;
225+
if (isString(layer)) {
226+
var resourceType = null;
227+
var layerUrl = '';
228+
229+
var fetchLayerBegin = 'fetch:';
230+
if (layer.startsWith(fetchLayerBegin)) {
231+
layerUrl = layer.substring(fetchLayerBegin.length);
232+
} else if (layer.indexOf(':fetch:', 0) !== -1) {
233+
var parts = layer.split(':', 3);
234+
resourceType = parts[0];
235+
layerUrl = parts[2];
229236
} else {
230-
var public_id = layer.public_id;
231-
var format = layer.format;
232-
var resource_type = layer.resource_type || "image";
233-
var type = layer.type || "upload";
234-
var text = layer.text;
235-
var style = null;
236-
var components = [];
237-
var noPublicId = isEmpty(public_id);
238-
if (!noPublicId) {
239-
public_id = public_id.replace(new RegExp("/", 'g'), ":");
240-
if (format != null) {
241-
public_id = `${public_id}.${format}`;
242-
}
243-
}
244-
if (isEmpty(text) && resource_type !== "text") {
245-
if (noPublicId) {
246-
throw "Must supply public_id for resource_type layer_parameter";
247-
}
248-
if (resource_type === "subtitles") {
249-
style = textStyle(layer);
250-
}
251-
} else {
252-
resource_type = "text";
253-
type = null;
254-
// type is ignored for text layers
255-
style = textStyle(layer);
256-
if (!isEmpty(text)) {
257-
var noStyle = isEmpty(style);
258-
if (!(noPublicId || noStyle) || noPublicId && noStyle) {
259-
throw "Must supply either style parameters or a public_id when providing text parameter in a text overlay/underlay";
260-
}
261-
var re = /\$\([a-zA-Z]\w*\)/g;
262-
var start = 0;
263-
var textSource = smart_escape(decodeURIComponent(text), /[,\/]/g);
264-
text = "";
265-
for (var res = re.exec(textSource); res; res = re.exec(textSource)) {
266-
text += smart_escape(textSource.slice(start, res.index));
267-
text += res[0];
268-
start = res.index + res[0].length;
269-
}
270-
text += encodeURIComponent(textSource.slice(start));
271-
}
272-
}
273-
if (resource_type !== "image") {
274-
components.push(resource_type);
275-
}
276-
if (type !== "upload") {
277-
components.push(type);
278-
}
279-
components.push(style);
237+
return layer;
238+
}
239+
240+
layer = {
241+
url: layerUrl,
242+
type: 'fetch'
243+
};
244+
245+
if (resourceType) {
246+
layer.resource_type = resourceType;
247+
}
248+
}
249+
250+
if (typeof layer !== 'object') {
251+
return layer;
252+
}
253+
254+
var _layer = layer,
255+
resource_type = _layer.resource_type,
256+
text = _layer.text,
257+
type = _layer.type,
258+
public_id = _layer.public_id,
259+
format = _layer.format,
260+
fetchUrl = _layer.url;
261+
262+
var components = [];
263+
264+
if (!isEmpty(text) && isEmpty(resource_type)) {
265+
resource_type = 'text';
266+
}
267+
268+
if (!isEmpty(fetchUrl) && isEmpty(type)) {
269+
type = 'fetch';
270+
}
271+
272+
if (!isEmpty(public_id) && !isEmpty(format)) {
273+
public_id = `${public_id}.${format}`;
274+
}
275+
276+
if (isEmpty(public_id) && resource_type !== 'text' && type !== 'fetch') {
277+
throw new Error('Must supply public_id for non-text overlay');
278+
}
279+
280+
if (!isEmpty(resource_type) && resource_type !== 'image') {
281+
components.push(resource_type);
282+
}
283+
284+
if (!isEmpty(type) && type !== 'upload') {
285+
components.push(type);
286+
}
287+
288+
if (resource_type === 'text' || resource_type === 'subtitles') {
289+
if (isEmpty(public_id) && isEmpty(text)) {
290+
throw new Error('Must supply either text or public_in in overlay');
291+
}
292+
293+
var textOptions = textStyle(layer);
294+
295+
if (!isEmpty(textOptions)) {
296+
components.push(textOptions);
297+
}
298+
299+
if (!isEmpty(public_id)) {
300+
public_id = public_id.replace('/', ':');
280301
components.push(public_id);
302+
}
303+
304+
if (!isEmpty(text)) {
305+
// const pattern = /(\$\([a-zA-Z]\w+\))/g;
306+
// const parts = text.split(pattern).filter(x => x !== '').map(part => {
307+
// let isVariable = part.match(pattern);
308+
// if (isVariable) {
309+
// return part;
310+
// }
311+
// // return smart_escape(smart_escape(part, /[,\/]/g));
312+
// return encodeURIComponent(part);
313+
// }).join('');
314+
// components.push(parts);
315+
var re = /\$\([a-zA-Z]\w*\)/g;
316+
var start = 0;
317+
var textSource = smart_escape(decodeURIComponent(text), /[,\/]/g);
318+
text = "";
319+
for (var res = re.exec(textSource); res; res = re.exec(textSource)) {
320+
text += smart_escape(textSource.slice(start, res.index));
321+
text += res[0];
322+
start = res.index + res[0].length;
323+
}
324+
text += encodeURIComponent(textSource.slice(start));
281325
components.push(text);
282-
result = compact(components).join(":");
283326
}
284-
} else if (/^fetch:.+/.test(layer)) {
285-
result = `fetch:${base64EncodeURL(layer.substr(6))}`;
327+
} else if (type === 'fetch') {
328+
var encodedUrl = base64EncodeURL(fetchUrl);
329+
components.push(encodedUrl);
286330
} else {
287-
result = layer;
331+
public_id = public_id.replace('/', ':');
332+
components.push(public_id);
288333
}
289-
return result;
334+
335+
return components.join(':');
290336
}
291337

292338
/**
@@ -1547,6 +1593,8 @@ function archive_params() {
15471593
};
15481594
}
15491595

1596+
exports.process_layer = process_layer;
1597+
15501598
exports.create_source_tag = function create_source_tag(src, source_type) {
15511599
var codecs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
15521600

lib/utils/encoding/smart_escape.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Based on CGI::unescape. In addition does not escape / :
2-
// smart_escape = (string)->
3-
// encodeURIComponent(string).replace(/%3A/g, ":").replace(/%2F/g, "/")
2+
// smart_escape = (string) => encodeURIComponent(string).replace(/%3A/g, ":").replace(/%2F/g, "/")
43
function smart_escape(string, unsafe = /([^a-zA-Z0-9_.\-\/:]+)/g) {
54
return string.replace(unsafe, function (match) {
65
return match.split("").map(function (c) {

0 commit comments

Comments
 (0)