@brandbrigade/ott-bb-player 1.0.43 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENCE +29 -0
- package/README.md +266 -218
- package/dist/OTTPlayer.js +272 -0
- package/package.json +22 -7
- package/src/Ads.js +82 -0
- package/src/Augmentor.js +1288 -0
- package/src/Composer3DBase.js +754 -0
- package/src/Composer3DForMainThread.js +131 -0
- package/src/Composer3DForWorker.js +80 -0
- package/src/Composer3DWorker.js +60 -0
- package/src/MetaDataDecoder.js +143 -0
- package/src/MetaDataFetcher.js +88 -0
- package/src/OTTPlayer.js +254 -0
- package/src/Socket.js +44 -0
- package/src/composer_worker.js +30 -0
- package/src/configs/OTT_Dev_Config_Debug.json +8 -0
- package/src/configs/OTT_Dev_Config_Debug_14fps.json +8 -0
- package/src/configs/OTT_Dev_Config_Debug_29fps.json +8 -0
- package/src/configs/OTT_Dev_Config_Debug_General.json +7 -0
- package/src/enums/RenderingMode.js +5 -0
- package/src/enums/SyncMethod.js +5 -0
- package/src/index.js +241 -0
- package/src/meta_worker.js +144 -0
- package/src/shaders/v1.js +87 -0
- package/src/shaders/v1Old.js +174 -0
- package/src/shaders/v2.js +193 -0
- package/src/test-pages/mp4/index.html +63 -0
- package/src/test-pages/mp4/index.js +23 -0
- package/src/test-pages/mp4/style.css +16 -0
- package/src/utils/FPSFetter.js +94 -0
- package/src/utils/MedianCalculator.js +27 -0
- package/src/utils/index.js +5 -0
- package/src/utils/isPowerOf2.js +3 -0
- package/src/utils/platform.js +191 -0
- package/src/utils/timeCodeUtils.js +274 -0
- package/js/OTTPlayer.js +0 -1
- package/mediakind.html +0 -273
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
export const FPSGetter = () => {
|
|
2
|
+
const possibleFps29_30 = [
|
|
3
|
+
30000 / 1001, //29.97
|
|
4
|
+
30 / 1, //30,0
|
|
5
|
+
];
|
|
6
|
+
const possibleFps59_60 = [
|
|
7
|
+
60000 / 1001, //59.94
|
|
8
|
+
60 / 1, ///60
|
|
9
|
+
];
|
|
10
|
+
let bestFPSMatches = [];
|
|
11
|
+
let deltaStorage = [];
|
|
12
|
+
let deltaCount = 0;
|
|
13
|
+
let lastMediaTimeForFPSGetting = -1;
|
|
14
|
+
let possibleFps
|
|
15
|
+
//let fps = 60;
|
|
16
|
+
let count = 0;
|
|
17
|
+
const addTime = (mediaTime) => {
|
|
18
|
+
count++;
|
|
19
|
+
//let fraction2PossibleFPS = new Map();
|
|
20
|
+
let minFraction = 999;
|
|
21
|
+
let minCandidateFps = 0;
|
|
22
|
+
if (lastMediaTimeForFPSGetting == -1) {
|
|
23
|
+
lastMediaTimeForFPSGetting = mediaTime;
|
|
24
|
+
return;
|
|
25
|
+
} else {
|
|
26
|
+
let delta = mediaTime - lastMediaTimeForFPSGetting;
|
|
27
|
+
if (deltaCount < 100) {
|
|
28
|
+
deltaStorage.push(delta);
|
|
29
|
+
deltaCount++;
|
|
30
|
+
return;
|
|
31
|
+
} else {
|
|
32
|
+
deltaStorage.push(delta);
|
|
33
|
+
deltaStorage.shift();
|
|
34
|
+
}
|
|
35
|
+
let total = 0;
|
|
36
|
+
for (let i = 0; i < deltaStorage.length; i++) {
|
|
37
|
+
total += deltaStorage[i];
|
|
38
|
+
}
|
|
39
|
+
delta = total / deltaStorage.length;
|
|
40
|
+
//console.log("delta= " + delta.toFixed(5) + " fps= " + (1/delta).toFixed(2));
|
|
41
|
+
if (1 / delta < 40) possibleFps = possibleFps29_30;
|
|
42
|
+
else possibleFps = possibleFps59_60;
|
|
43
|
+
}
|
|
44
|
+
//possibleFps = possibleFps59_60;
|
|
45
|
+
lastMediaTimeForFPSGetting = mediaTime;
|
|
46
|
+
|
|
47
|
+
for (let i = 0; i < possibleFps.length; ++i) {
|
|
48
|
+
let candidateFps = possibleFps[i];
|
|
49
|
+
let dblFrame = mediaTime * candidateFps;
|
|
50
|
+
let intFrame = Math.round(dblFrame);
|
|
51
|
+
let fraction = Math.abs(dblFrame - intFrame);
|
|
52
|
+
if (fraction < minFraction) {
|
|
53
|
+
minFraction = fraction;
|
|
54
|
+
minCandidateFps = candidateFps;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
//fraction2PossibleFPS.set(fraction, candidateFps);
|
|
58
|
+
}
|
|
59
|
+
let bestFPSMatch = minCandidateFps; //fraction2PossibleFPS.entries().next().value[1];
|
|
60
|
+
bestFPSMatches.push(bestFPSMatch);
|
|
61
|
+
//console.log("bestFPSMatch = " + bestFPSMatch);
|
|
62
|
+
if (count > 1000) bestFPSMatches.shift(); //deleting the first el
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const getProbableFPS = () => {
|
|
66
|
+
let count = {};
|
|
67
|
+
let mostOccurringValue;
|
|
68
|
+
let maxCount = 0;
|
|
69
|
+
|
|
70
|
+
// Count the occurrences of each value in the array
|
|
71
|
+
for (let i = 0; i < bestFPSMatches.length; i++) {
|
|
72
|
+
let value = bestFPSMatches[i];
|
|
73
|
+
count[value] = (count[value] || 0) + 1;
|
|
74
|
+
|
|
75
|
+
// Update the most occurring value and its count if necessary
|
|
76
|
+
if (count[value] > maxCount) {
|
|
77
|
+
mostOccurringValue = value;
|
|
78
|
+
maxCount = count[value];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return mostOccurringValue;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const howMany = () => {
|
|
86
|
+
return count;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
addTime: addTime,
|
|
91
|
+
getProbableFPS: getProbableFPS,
|
|
92
|
+
howMany: howMany,
|
|
93
|
+
};
|
|
94
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const MedianCalculator = (maxSize_) => {
|
|
2
|
+
let maxSize = maxSize_ || 9999999999;
|
|
3
|
+
let values = [];
|
|
4
|
+
let count = 0;
|
|
5
|
+
|
|
6
|
+
const add = (value) => {
|
|
7
|
+
++count;
|
|
8
|
+
values.push(value);
|
|
9
|
+
while (values.length > maxSize) values.shift();
|
|
10
|
+
};
|
|
11
|
+
const getMedian = () => {
|
|
12
|
+
if (values.length == 0) return -1;
|
|
13
|
+
let sortedValues = Array.from(values).sort((a, b) => {
|
|
14
|
+
return a - b;
|
|
15
|
+
});
|
|
16
|
+
return sortedValues[Math.floor(sortedValues.length / 2)];
|
|
17
|
+
};
|
|
18
|
+
const howMany = () => {
|
|
19
|
+
return count;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
add,
|
|
24
|
+
getMedian,
|
|
25
|
+
howMany,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
export const Platform = (() => {
|
|
2
|
+
const getCurrentPlatform = () => {
|
|
3
|
+
const userAgent = navigator.userAgent;
|
|
4
|
+
if (/windows/i.test(userAgent)) {
|
|
5
|
+
return "Windows";
|
|
6
|
+
} else if (/android/i.test(userAgent)) {
|
|
7
|
+
return "Android";
|
|
8
|
+
} else if (/iphone|ipad|ipod/i.test(userAgent)) {
|
|
9
|
+
return "iOS";
|
|
10
|
+
} else if (/mac/i.test(userAgent)) {
|
|
11
|
+
return "Mac"; //tmp alal
|
|
12
|
+
let isIPadAnyhow =
|
|
13
|
+
"ontouchstart" in window ||
|
|
14
|
+
navigator.maxTouchPoints > 0 ||
|
|
15
|
+
navigator.msMaxTouchPoints > 0;
|
|
16
|
+
if (isIPadAnyhow) return "iPad";
|
|
17
|
+
else return "Mac";
|
|
18
|
+
} else if (/ipad/i.test(userAgent)) {
|
|
19
|
+
return "iPad";
|
|
20
|
+
} else {
|
|
21
|
+
return "Something else";
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const isMac = () => {
|
|
25
|
+
let platform = getCurrentPlatform();
|
|
26
|
+
return platform == "Mac";
|
|
27
|
+
};
|
|
28
|
+
const isiPad = () => {
|
|
29
|
+
let platform = getCurrentPlatform();
|
|
30
|
+
return platform == "iPad";
|
|
31
|
+
};
|
|
32
|
+
const isiPhone = () => {
|
|
33
|
+
let platform = getCurrentPlatform();
|
|
34
|
+
return platform == "iOS";
|
|
35
|
+
};
|
|
36
|
+
const isApple = () => {
|
|
37
|
+
let platform = getCurrentPlatform();
|
|
38
|
+
return platform == "iOS" || platform == "Mac" || platform == "iPad";
|
|
39
|
+
};
|
|
40
|
+
const isWindows = () => {
|
|
41
|
+
//return true;
|
|
42
|
+
let platform = getCurrentPlatform();
|
|
43
|
+
return platform == "Windows";
|
|
44
|
+
};
|
|
45
|
+
const isAndroid = () => {
|
|
46
|
+
let platform = getCurrentPlatform();
|
|
47
|
+
return platform == "Android";
|
|
48
|
+
};
|
|
49
|
+
const getDeviceDescription = () => {
|
|
50
|
+
let deviceType = getCurrentPlatform();
|
|
51
|
+
if (deviceType == "Windows") return "a Windows PC";
|
|
52
|
+
else if (deviceType == "Android") return "an Android phone";
|
|
53
|
+
else if (deviceType == "iOS") return "an iPhone";
|
|
54
|
+
else if (deviceType == "Mac") return "a Mac";
|
|
55
|
+
else if (deviceType == "iPad") return "an iPad";
|
|
56
|
+
else return "an Unknown device";
|
|
57
|
+
};
|
|
58
|
+
const getDeviceName = () => {
|
|
59
|
+
let module = {
|
|
60
|
+
options: [],
|
|
61
|
+
header: [
|
|
62
|
+
navigator.platform,
|
|
63
|
+
navigator.userAgent,
|
|
64
|
+
navigator.appVersion,
|
|
65
|
+
navigator.vendor,
|
|
66
|
+
window.opera,
|
|
67
|
+
],
|
|
68
|
+
dataos: [
|
|
69
|
+
{ name: "Windows Phone", value: "Windows Phone", version: "OS" },
|
|
70
|
+
{ name: "Windows", value: "Win", version: "NT" },
|
|
71
|
+
{ name: "iPhone", value: "iPhone", version: "OS" },
|
|
72
|
+
{ name: "iPad", value: "iPad", version: "OS" },
|
|
73
|
+
{ name: "Kindle", value: "Silk", version: "Silk" },
|
|
74
|
+
{ name: "Android", value: "Android", version: "Android" },
|
|
75
|
+
{ name: "PlayBook", value: "PlayBook", version: "OS" },
|
|
76
|
+
{ name: "BlackBerry", value: "BlackBerry", version: "/" },
|
|
77
|
+
{ name: "Macintosh", value: "Mac", version: "OS X" },
|
|
78
|
+
{ name: "Linux", value: "Linux", version: "rv" },
|
|
79
|
+
{ name: "Palm", value: "Palm", version: "PalmOS" },
|
|
80
|
+
],
|
|
81
|
+
databrowser: [
|
|
82
|
+
{ name: "Chrome", value: "Chrome", version: "Chrome" },
|
|
83
|
+
{ name: "Firefox", value: "Firefox", version: "Firefox" },
|
|
84
|
+
{ name: "Safari", value: "Safari", version: "Version" },
|
|
85
|
+
{ name: "Internet Explorer", value: "MSIE", version: "MSIE" },
|
|
86
|
+
{ name: "Opera", value: "Opera", version: "Opera" },
|
|
87
|
+
{ name: "BlackBerry", value: "CLDC", version: "CLDC" },
|
|
88
|
+
{ name: "Mozilla", value: "Mozilla", version: "Mozilla" },
|
|
89
|
+
],
|
|
90
|
+
init: function () {
|
|
91
|
+
let agent = this.header.join(" "),
|
|
92
|
+
os = this.matchItem(agent, this.dataos),
|
|
93
|
+
browser = this.matchItem(agent, this.databrowser);
|
|
94
|
+
|
|
95
|
+
return { os: os, browser: browser };
|
|
96
|
+
},
|
|
97
|
+
matchItem: function (string, data) {
|
|
98
|
+
let i = 0,
|
|
99
|
+
j = 0,
|
|
100
|
+
html = "",
|
|
101
|
+
regex,
|
|
102
|
+
regexv,
|
|
103
|
+
match,
|
|
104
|
+
matches,
|
|
105
|
+
version;
|
|
106
|
+
|
|
107
|
+
for (i = 0; i < data.length; i += 1) {
|
|
108
|
+
regex = new RegExp(data[i].value, "i");
|
|
109
|
+
match = regex.test(string);
|
|
110
|
+
if (match) {
|
|
111
|
+
regexv = new RegExp(data[i].version + "[- /:;]([\\d._]+)", "i");
|
|
112
|
+
matches = string.match(regexv);
|
|
113
|
+
version = "";
|
|
114
|
+
if (matches) {
|
|
115
|
+
if (matches[1]) {
|
|
116
|
+
matches = matches[1];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (matches) {
|
|
120
|
+
matches = matches.split(/[._]+/);
|
|
121
|
+
for (j = 0; j < matches.length; j += 1) {
|
|
122
|
+
if (j === 0) {
|
|
123
|
+
version += matches[j] + ".";
|
|
124
|
+
} else {
|
|
125
|
+
version += matches[j];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
version = "0";
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
name: data[i].name,
|
|
133
|
+
version: parseFloat(version),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return { name: "unknown", version: 0 };
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
let e = module.init();
|
|
142
|
+
return e.os.name;
|
|
143
|
+
};
|
|
144
|
+
const getBrowserName = () => {
|
|
145
|
+
const userAgent = navigator.userAgent;
|
|
146
|
+
|
|
147
|
+
if (userAgent.indexOf("Chrome") > -1 && userAgent.indexOf("Edge") === -1) {
|
|
148
|
+
return "Chrome";
|
|
149
|
+
} else if (
|
|
150
|
+
userAgent.indexOf("Safari") > -1 &&
|
|
151
|
+
userAgent.indexOf("Chrome") === -1
|
|
152
|
+
) {
|
|
153
|
+
return "Safari";
|
|
154
|
+
} else if (userAgent.indexOf("Firefox") > -1) {
|
|
155
|
+
return "Firefox";
|
|
156
|
+
} else if (
|
|
157
|
+
userAgent.indexOf("MSIE") > -1 ||
|
|
158
|
+
userAgent.indexOf("Trident") > -1
|
|
159
|
+
) {
|
|
160
|
+
return "Internet Explorer";
|
|
161
|
+
} else if (userAgent.indexOf("Edge") > -1) {
|
|
162
|
+
return "Edge";
|
|
163
|
+
} else {
|
|
164
|
+
return "Unknown";
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const isSafariMac = () => {
|
|
168
|
+
return isMac() && getBrowserName() == "Safari";
|
|
169
|
+
};
|
|
170
|
+
const isChromeMac = () => {
|
|
171
|
+
return isMac() && getBrowserName() == "Chrome";
|
|
172
|
+
};
|
|
173
|
+
const isChromeWin = () => {
|
|
174
|
+
return isWindows() && getBrowserName() == "Chrome";
|
|
175
|
+
};
|
|
176
|
+
return {
|
|
177
|
+
getDeviceName,
|
|
178
|
+
getCurrentPlatform,
|
|
179
|
+
isApple,
|
|
180
|
+
isWindows,
|
|
181
|
+
isAndroid,
|
|
182
|
+
isMac,
|
|
183
|
+
isiPhone,
|
|
184
|
+
isiPad,
|
|
185
|
+
getDeviceDescription,
|
|
186
|
+
getBrowserName,
|
|
187
|
+
isSafariMac,
|
|
188
|
+
isChromeMac,
|
|
189
|
+
isChromeWin,
|
|
190
|
+
};
|
|
191
|
+
})();
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { Platform } from "./platform";
|
|
2
|
+
|
|
3
|
+
const padZero = (num) => {
|
|
4
|
+
return num.toString().padStart(2, "0");
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const timecodeDelimeter = ":";
|
|
8
|
+
|
|
9
|
+
export const printTimecode = (timecode, duplicated, dot2) => {
|
|
10
|
+
let str = "";
|
|
11
|
+
if (Array.isArray(timecode)) {
|
|
12
|
+
str = [
|
|
13
|
+
padZero(timecode[0]),
|
|
14
|
+
padZero(timecode[1]),
|
|
15
|
+
padZero(timecode[2]),
|
|
16
|
+
padZero(timecode[3]),
|
|
17
|
+
].join(":");
|
|
18
|
+
if (dot2 == true) {
|
|
19
|
+
if (timecode[4] == 1 && (duplicated === undefined || duplicated))
|
|
20
|
+
str += ".2";
|
|
21
|
+
else str += ".1";
|
|
22
|
+
} else {
|
|
23
|
+
if (timecode[4] == 1 && (duplicated === undefined || duplicated))
|
|
24
|
+
str += ".1";
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
str =
|
|
28
|
+
("0" + timecode.h).slice(-2) +
|
|
29
|
+
timecodeDelimeter +
|
|
30
|
+
("0" + timecode.m).slice(-2) +
|
|
31
|
+
timecodeDelimeter +
|
|
32
|
+
("0" + timecode.s).slice(-2) +
|
|
33
|
+
timecodeDelimeter +
|
|
34
|
+
("0" + timecode.f).slice(-2);
|
|
35
|
+
if (duplicated) str += "." + (timecode.field ? "1" : "2");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return str;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const str2TimeCode = (str, delimiter) => {
|
|
42
|
+
const list = str.split(delimiter);
|
|
43
|
+
const timecode = {
|
|
44
|
+
h: parseInt(list[0]),
|
|
45
|
+
m: parseInt(list[1]),
|
|
46
|
+
s: parseInt(list[2]),
|
|
47
|
+
f: parseInt(list[3]),
|
|
48
|
+
};
|
|
49
|
+
return timecode;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const timeCodeStr2TimeCodeArray = (timecodeStr) => {
|
|
53
|
+
let tokens = timecodeStr.split(":");
|
|
54
|
+
if (tokens.length != 4) {
|
|
55
|
+
console.error("timeCodeStr2TimeCodeArray: Failed to parse " + timecodeStr);
|
|
56
|
+
return [0, 0, 0, 0, 0];
|
|
57
|
+
}
|
|
58
|
+
let timeCodeArray = [
|
|
59
|
+
parseInt(tokens[0]), //hours
|
|
60
|
+
parseInt(tokens[1]), //minutes
|
|
61
|
+
parseInt(tokens[2]),
|
|
62
|
+
]; //seconds
|
|
63
|
+
if (tokens[3].indexOf(".") >= 0) {
|
|
64
|
+
let framesAndField = tokens[3].split(".");
|
|
65
|
+
timeCodeArray.push(parseInt(framesAndField[0])); //frames
|
|
66
|
+
timeCodeArray.push(parseInt(framesAndField[1])); //field
|
|
67
|
+
} else {
|
|
68
|
+
timeCodeArray.push(parseInt(tokens[3])); //frames
|
|
69
|
+
timeCodeArray.push(0); //field
|
|
70
|
+
}
|
|
71
|
+
return timeCodeArray;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const timecode2Frames = (timecode, fps, duplicated) => {
|
|
75
|
+
//timecode [hh,mm,ss,ff,.1] //.1= 1|0, fps (60,59.94,30.29.96), duplicated (true|false)
|
|
76
|
+
// finding counting fps and dropped frames
|
|
77
|
+
let countingFps = 60;
|
|
78
|
+
let dropFrames = 0;
|
|
79
|
+
if (Math.floor(fps) == 60) {
|
|
80
|
+
countingFps = 60;
|
|
81
|
+
dropFrames = 0;
|
|
82
|
+
} else if (Math.floor(fps) == 59) {
|
|
83
|
+
countingFps = 60;
|
|
84
|
+
dropFrames = 4;
|
|
85
|
+
} else if (Math.floor(fps) == 30) {
|
|
86
|
+
countingFps = 30;
|
|
87
|
+
dropFrames = 0;
|
|
88
|
+
} else if (Math.floor(fps) == 29) {
|
|
89
|
+
countingFps = 30;
|
|
90
|
+
dropFrames = 2;
|
|
91
|
+
}
|
|
92
|
+
let result = 0;
|
|
93
|
+
let framesPerMinute = Math.floor(fps * 60); //3600|3596|1800|1798
|
|
94
|
+
let framesPer10Minutes = Math.floor(fps * 60 * 10); //36000|35964|18000|17982
|
|
95
|
+
let framesPerHour = framesPer10Minutes * 6;
|
|
96
|
+
let hh = timecode[0];
|
|
97
|
+
let mm = timecode[1];
|
|
98
|
+
let ss = timecode[2];
|
|
99
|
+
let ff = timecode[3];
|
|
100
|
+
let dotOne = timecode[4]; //(timecode[4]==0)?false:true;
|
|
101
|
+
result += hh * framesPerHour;
|
|
102
|
+
result += mm * (countingFps * 60);
|
|
103
|
+
result += ss * countingFps;
|
|
104
|
+
if (duplicated) result += ff * 2 + dotOne;
|
|
105
|
+
else result += ff;
|
|
106
|
+
result -= dropFrames * mm;
|
|
107
|
+
result += dropFrames * Math.floor(mm / 10); //drop Frames on every minute exept every 10th
|
|
108
|
+
return result;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const frames2Timecode = (frames, fps, duplicated) => {
|
|
112
|
+
//timecode [hh,mm,ss,ff,.1] //.1= 1|0, fps (60,59.94,30.29.96), duplicated (true|false)
|
|
113
|
+
|
|
114
|
+
// finding counting fps and dropped frames
|
|
115
|
+
let countingFps = 60;
|
|
116
|
+
let dropFrames = 0;
|
|
117
|
+
if (Math.floor(fps) == 60) {
|
|
118
|
+
countingFps = 60;
|
|
119
|
+
dropFrames = 0;
|
|
120
|
+
} else if (Math.floor(fps) == 59) {
|
|
121
|
+
countingFps = 60;
|
|
122
|
+
dropFrames = 4;
|
|
123
|
+
} else if (Math.floor(fps) == 30) {
|
|
124
|
+
countingFps = 30;
|
|
125
|
+
dropFrames = 0;
|
|
126
|
+
} else if (Math.floor(fps) == 29) {
|
|
127
|
+
countingFps = 30;
|
|
128
|
+
dropFrames = 2;
|
|
129
|
+
}
|
|
130
|
+
let result = 0;
|
|
131
|
+
let framesPerMinute = Math.floor(fps * 60); //3600|3596|1800|1798
|
|
132
|
+
let framesPer10Minutes = Math.floor(fps * 60 * 10); //36000|35964|18000|17982
|
|
133
|
+
let framesPerHour = framesPer10Minutes * 6;
|
|
134
|
+
|
|
135
|
+
let framesLeft = frames;
|
|
136
|
+
let hh = Math.floor(framesLeft / framesPerHour);
|
|
137
|
+
framesLeft -= hh * framesPerHour;
|
|
138
|
+
let mm10 = Math.floor(framesLeft / framesPer10Minutes);
|
|
139
|
+
|
|
140
|
+
framesLeft -= mm10 * framesPer10Minutes;
|
|
141
|
+
|
|
142
|
+
if (framesLeft >= countingFps * 60)
|
|
143
|
+
//3600 (in 59.94fps)
|
|
144
|
+
framesLeft +=
|
|
145
|
+
dropFrames *
|
|
146
|
+
(Math.floor((framesLeft - countingFps * 60) / framesPerMinute) + 1); //3600 /3596 (in 59.94fps)
|
|
147
|
+
|
|
148
|
+
//framesLeft-= Math.floor(framesLeft / framesPerMinute)*(dropFrames)
|
|
149
|
+
|
|
150
|
+
let mm = Math.floor(framesLeft / (countingFps * 60)); //3600 (in 59.94fps)
|
|
151
|
+
|
|
152
|
+
framesLeft -= mm * (countingFps * 60); //3600 (in 59.94fps)
|
|
153
|
+
|
|
154
|
+
let ss = Math.floor(framesLeft / countingFps);
|
|
155
|
+
framesLeft -= ss * countingFps;
|
|
156
|
+
let ff = framesLeft;
|
|
157
|
+
mm += mm10 * 10;
|
|
158
|
+
|
|
159
|
+
let dotOne = 0;
|
|
160
|
+
if (duplicated) {
|
|
161
|
+
dotOne = ff % 2;
|
|
162
|
+
ff = Math.floor(ff / 2);
|
|
163
|
+
}
|
|
164
|
+
let returnTimecode = [hh, mm, ss, ff, dotOne];
|
|
165
|
+
return returnTimecode;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export const timeCodeAddFrames = (tc, framesToAdd, fps) => {
|
|
169
|
+
let duplicated = fps > 30;
|
|
170
|
+
let frames = timecode2Frames(tc, fps, duplicated);
|
|
171
|
+
frames += framesToAdd;
|
|
172
|
+
return frames2Timecode(frames, fps, duplicated);
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
export const timeCodeArray2TimeCodeJson = (timeCodeArray) => {
|
|
176
|
+
return {
|
|
177
|
+
h: timeCodeArray[0],
|
|
178
|
+
m: timeCodeArray[1],
|
|
179
|
+
s: timeCodeArray[2],
|
|
180
|
+
f: timeCodeArray[3],
|
|
181
|
+
field: timeCodeArray[4],
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export const timeDate2TCString = (timeDate, fps) => {
|
|
186
|
+
let tc = timeDate2TC(timeDate, fps);
|
|
187
|
+
//didn't check new version
|
|
188
|
+
if (fps > 59) {
|
|
189
|
+
return printTimecode(tcFromMessage, true);
|
|
190
|
+
} else {
|
|
191
|
+
return printTimecode(tcFromMessage, false);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export const timeDate2TC = (timeDate, fps) => {
|
|
196
|
+
let timeStampStr = "";
|
|
197
|
+
if (Platform.isApple()) {
|
|
198
|
+
timeStampStr = timeDate;
|
|
199
|
+
} else {
|
|
200
|
+
timeStampStr = timeDate.toISOString();
|
|
201
|
+
}
|
|
202
|
+
let timeStr = timeStampStr.split("T")[1];
|
|
203
|
+
let arr1 = timeStr.split(":");
|
|
204
|
+
let hrs = parseInt(arr1[0]);
|
|
205
|
+
let mins = parseInt(arr1[1]);
|
|
206
|
+
let arr2 = arr1[2].split(".");
|
|
207
|
+
let secs = parseInt(arr2[0]);
|
|
208
|
+
let msec = parseInt(arr2[1].substring(0, 3));
|
|
209
|
+
//let frames = Math.round(((msec / 1000) * fps)+0.02 /*+ 0.45*/);
|
|
210
|
+
if (fps > 59) {
|
|
211
|
+
//let field = (frames % 2 == 0 ? 1 : 2);
|
|
212
|
+
//frames = Math.floor(frames / 2);
|
|
213
|
+
//let returnTimecode = [hrs,mins,secs,frames,field-1];
|
|
214
|
+
let allFrames = Math.round(
|
|
215
|
+
(msec / 1000 + secs + mins * 60 + hrs * 60 * 60) * fps,
|
|
216
|
+
);
|
|
217
|
+
let returnTimecode = frames2Timecode(allFrames, fps, true);
|
|
218
|
+
return returnTimecode;
|
|
219
|
+
} else {
|
|
220
|
+
//let returnTimecode = [hrs,mins,secs,frames,0];
|
|
221
|
+
//let returnTimecode = BB.Utils.TimeCodesFramesTranslator.frames2Timecode(frames+secs*fps+mins*fps*60+hrs*fps*60*60,fps,false);
|
|
222
|
+
let allFrames = Math.round(
|
|
223
|
+
(msec / 1000 + secs + mins * 60 + hrs * 60 * 60) * fps,
|
|
224
|
+
);
|
|
225
|
+
let returnTimecode = frames2Timecode(allFrames, fps, false);
|
|
226
|
+
return returnTimecode;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
export const timeCode2Str = (timecode) => {
|
|
231
|
+
const str = ("0" + timecode.h).slice(-2) + timecodeDelimeter +
|
|
232
|
+
("0" + timecode.m).slice(-2) + timecodeDelimeter +
|
|
233
|
+
("0" + timecode.s).slice(-2) + timecodeDelimeter +
|
|
234
|
+
("0" + timecode.f).slice(-2)
|
|
235
|
+
|
|
236
|
+
return str
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
export const addSecondsToTimeCode = (timecode, seconds) => {
|
|
240
|
+
let ret = { ...timecode }; //cloning araay
|
|
241
|
+
ret.s += seconds;
|
|
242
|
+
if (ret.s >= 60) {
|
|
243
|
+
ret.s = 0;
|
|
244
|
+
ret.m++;
|
|
245
|
+
if (ret.m >= 60) {
|
|
246
|
+
ret.m = 0;
|
|
247
|
+
ret.h++;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return ret;
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export const getNextTimeCode_TC = (tc, seconds = 0) => {
|
|
254
|
+
let timecode = str2TimeCode(tc, ':');
|
|
255
|
+
if (seconds) timecode = addSecondsToTimeCode(timecode, seconds);
|
|
256
|
+
return timecode;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export const getNextTimeCode = (tc, seconds = 0) => {
|
|
260
|
+
let timecode = getNextTimeCode_TC(tc, seconds);
|
|
261
|
+
return timeCode2Str(timecode);
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
export const isTCBigger = (tc1, tc2) => {
|
|
265
|
+
//return true iif tc1 > tc2
|
|
266
|
+
if (tc1.h > tc2.h) return true;
|
|
267
|
+
else if (tc1.h < tc2.h) return false;
|
|
268
|
+
else if (tc1.m > tc2.m) return true;
|
|
269
|
+
else if (tc1.m < tc2.m) return false;
|
|
270
|
+
else if (tc1.s > tc2.s) return true;
|
|
271
|
+
else if (tc1.s < tc2.s) return false;
|
|
272
|
+
else if (tc1.f > tc2.f) return true;
|
|
273
|
+
else return false;
|
|
274
|
+
};
|