expo-video-metadata 1.3.0 → 1.4.0
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/.yarnrc.yml +3 -0
- package/build/ExpoVideoMetadataModule.js +1 -1
- package/build/ExpoVideoMetadataModule.js.map +1 -1
- package/build/ExpoVideoMetadataModule.web.d.ts.map +1 -1
- package/build/ExpoVideoMetadataModule.web.js +21 -10
- package/build/ExpoVideoMetadataModule.web.js.map +1 -1
- package/package.json +6 -7
- package/src/ExpoVideoMetadataModule.ts +1 -1
- package/src/ExpoVideoMetadataModule.web.ts +21 -17
package/.yarnrc.yml
ADDED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoVideoMetadataModule.js","sourceRoot":"","sources":["../src/ExpoVideoMetadataModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ExpoVideoMetadataModule.js","sourceRoot":"","sources":["../src/ExpoVideoMetadataModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAC3C,eAAe,mBAAmB,CAAC,mBAAmB,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from \"expo\";\nexport default requireNativeModule(\"ExpoVideoMetadata\");\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoVideoMetadataModule.web.d.ts","sourceRoot":"","sources":["../src/ExpoVideoMetadataModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,WAAW,EACZ,MAAM,2BAA2B,CAAC;AAEnC,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,UAAW,SAAQ,KAAK;IAChC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,UAAW,SAAQ,KAAK;IAChC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;AAExB,UAAU,0BAA2B,SAAQ,gBAAgB;IAC3D,WAAW,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,aAAa,CAAC,IAAI,WAAW,CAAC;CAC/B;;;oCAKiC,0BAA0B;6BAkB9C,MAAM,YACP,WAAW,GACnB,
|
|
1
|
+
{"version":3,"file":"ExpoVideoMetadataModule.web.d.ts","sourceRoot":"","sources":["../src/ExpoVideoMetadataModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,WAAW,EACZ,MAAM,2BAA2B,CAAC;AAEnC,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,UAAW,SAAQ,KAAK;IAChC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,UAAW,SAAQ,KAAK;IAChC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;AAExB,UAAU,0BAA2B,SAAQ,gBAAgB;IAC3D,WAAW,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,aAAa,CAAC,IAAI,WAAW,CAAC;CAC/B;;;oCAKiC,0BAA0B;6BAkB9C,MAAM,YACP,WAAW,GACnB,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;oCA6B5B,MAAM,GAAG,MAAM;qBAKxB,MAAM,YAAW,WAAW,GAAQ,OAAO,CAAC,MAAM,CAAC;yBAgBhE,WAAW,YACV,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC;;AA3E7B,wBA4JE"}
|
|
@@ -14,20 +14,31 @@ export default {
|
|
|
14
14
|
return videoTrack.getSettings().frameRate ?? 0;
|
|
15
15
|
},
|
|
16
16
|
async getAudioBuffer(audioUrl, options = {}) {
|
|
17
|
-
const audioContext = new (window.AudioContext ||
|
|
18
|
-
window.webkitAudioContext)();
|
|
19
17
|
try {
|
|
20
18
|
const response = await fetch(audioUrl, options);
|
|
21
19
|
const arrayBuffer = await response.arrayBuffer();
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const audioContext = new (window.AudioContext ||
|
|
21
|
+
window.webkitAudioContext)();
|
|
22
|
+
try {
|
|
23
|
+
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
|
|
24
|
+
return {
|
|
25
|
+
sampleRate: audioBuffer.sampleRate,
|
|
26
|
+
numberOfChannels: audioBuffer.numberOfChannels,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (decodeError) {
|
|
30
|
+
console.info("Error decoding audio data (no audio?):", decodeError);
|
|
31
|
+
// If decoding fails, assume no audio
|
|
32
|
+
return { sampleRate: 0, numberOfChannels: 0 };
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
await audioContext.close();
|
|
36
|
+
}
|
|
25
37
|
}
|
|
26
38
|
catch (error) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
await audioContext.close();
|
|
39
|
+
console.info("Error decoding audio data (CORS?):", error);
|
|
40
|
+
// If any error occurs during the process, return default values silently
|
|
41
|
+
return { sampleRate: 0, numberOfChannels: 0 };
|
|
31
42
|
}
|
|
32
43
|
},
|
|
33
44
|
getBase64FileSize(base64String) {
|
|
@@ -44,7 +55,7 @@ export default {
|
|
|
44
55
|
return contentLength ? parseInt(contentLength, 10) : 0;
|
|
45
56
|
}
|
|
46
57
|
catch (error) {
|
|
47
|
-
console.
|
|
58
|
+
console.info("Error fetching file size for URL (CORS?):", url, error);
|
|
48
59
|
return 0;
|
|
49
60
|
}
|
|
50
61
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoVideoMetadataModule.web.js","sourceRoot":"","sources":["../src/ExpoVideoMetadataModule.web.ts"],"names":[],"mappings":"AA+BA,eAAe;IACb,IAAI,EAAE,mBAAmB;IAEzB,iBAAiB,CAAC,YAAwC;QACxD,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;YACnD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa,EAAE,CAAC;QAC5C,MAAM,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;QAE7C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YACrC,OAAO,CAAC,CAAC;QACX,CAAC;QAED,OAAO,UAAU,CAAC,WAAW,EAAE,CAAC,SAAS,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,QAAgB,EAChB,UAAuB,EAAE;QAEzB,
|
|
1
|
+
{"version":3,"file":"ExpoVideoMetadataModule.web.js","sourceRoot":"","sources":["../src/ExpoVideoMetadataModule.web.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n VideoInfoOptions,\n VideoInfoResult,\n VideoSource,\n} from \"./ExpoVideoMetadata.types\";\n\ninterface Track {\n id: string;\n kind: string;\n label: string;\n language: string;\n}\n\ninterface AudioTrack extends Track {\n enabled: boolean;\n}\n\ninterface VideoTrack extends Track {\n selected: boolean;\n}\n\ntype TrackList<T> = T[];\n\ninterface HTMLVideoElementWithTracks extends HTMLVideoElement {\n videoTracks?: TrackList<VideoTrack>;\n audioTracks?: TrackList<AudioTrack>;\n mozHasAudio?: boolean;\n webkitAudioDecodedByteCount?: number;\n captureStream?(): MediaStream;\n}\n\nexport default {\n name: \"ExpoVideoMetadata\",\n\n getVideoFrameRate(videoElement: HTMLVideoElementWithTracks) {\n if (!videoElement.captureStream) {\n console.info(\"captureStream method not supported\");\n return 0;\n }\n\n const stream = videoElement.captureStream();\n const [videoTrack] = stream.getVideoTracks();\n\n if (!videoTrack) {\n console.info(\"No video track found\");\n return 0;\n }\n\n return videoTrack.getSettings().frameRate ?? 0;\n },\n\n async getAudioBuffer(\n audioUrl: string,\n options: RequestInit = {}\n ): Promise<{ sampleRate: number; numberOfChannels: number }> {\n try {\n const response = await fetch(audioUrl, options);\n const arrayBuffer = await response.arrayBuffer();\n\n const audioContext = new (window.AudioContext ||\n (window as any).webkitAudioContext)();\n\n try {\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n return {\n sampleRate: audioBuffer.sampleRate,\n numberOfChannels: audioBuffer.numberOfChannels,\n };\n } catch (decodeError) {\n console.info(\"Error decoding audio data (no audio?):\", decodeError);\n // If decoding fails, assume no audio\n return { sampleRate: 0, numberOfChannels: 0 };\n } finally {\n await audioContext.close();\n }\n } catch (error) {\n console.info(\"Error decoding audio data (CORS?):\", error);\n\n // If any error occurs during the process, return default values silently\n return { sampleRate: 0, numberOfChannels: 0 };\n }\n },\n\n getBase64FileSize(base64String: string): number {\n const base64Data = base64String.replace(/^data:.+;base64,/, \"\");\n return atob(base64Data).length;\n },\n\n async getFileSize(url: string, options: RequestInit = {}): Promise<number> {\n if (url.startsWith(\"data:\")) {\n return this.getBase64FileSize(url);\n }\n\n try {\n const response = await fetch(url, { method: \"HEAD\", ...options });\n const contentLength = response.headers.get(\"Content-Length\");\n return contentLength ? parseInt(contentLength, 10) : 0;\n } catch (error) {\n console.info(\"Error fetching file size for URL (CORS?):\", url, error);\n return 0;\n }\n },\n\n async getVideoInfo(\n source: VideoSource,\n options: VideoInfoOptions = {}\n ): Promise<VideoInfoResult> {\n const video = document.createElement(\"video\") as HTMLVideoElementWithTracks;\n let videoUrl = \"\";\n\n if (typeof source === \"string\") {\n videoUrl = source;\n } else if (source instanceof File || source instanceof Blob) {\n videoUrl = URL.createObjectURL(source);\n }\n\n Object.assign(video, {\n crossOrigin: \"anonymous\",\n autoplay: true,\n muted: true,\n playsInline: true,\n });\n\n const resetVideo = () => {\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n video.remove();\n // Revoke the object URL if it was created\n if (source instanceof File || source instanceof Blob) {\n URL.revokeObjectURL(videoUrl);\n }\n };\n\n try {\n await new Promise<void>((resolve, reject) => {\n // Can't use `loadedmetadata` event because it does not contain videoTracks, audioTracks and other metadata\n video.onloadeddata = () => resolve();\n video.onerror = () =>\n reject(new Error(\"Failed to load video metadata\"));\n video.src = videoUrl;\n video.load();\n video.pause();\n });\n\n const { duration, videoWidth: width, videoHeight: height } = video;\n const videoTrack = video.videoTracks?.[0];\n const audioTrack = video.audioTracks?.[0];\n\n const hasAudio =\n Boolean(video.audioTracks?.length) ||\n video.mozHasAudio ||\n Boolean(video.webkitAudioDecodedByteCount);\n\n const fileSize =\n source instanceof File || source instanceof Blob\n ? source.size\n : await this.getFileSize(videoUrl, options);\n\n const bitRate =\n fileSize && duration ? Math.floor(fileSize / duration) : 0;\n\n const { numberOfChannels: audioChannels, sampleRate: audioSampleRate } =\n await this.getAudioBuffer(videoUrl);\n\n const fps = this.getVideoFrameRate(video);\n\n return {\n duration,\n width,\n height,\n bitRate,\n fileSize,\n hasAudio,\n audioSampleRate,\n isHDR: null, // not supported on web\n audioCodec: audioTrack?.label ?? \"\",\n codec: videoTrack?.label ?? \"\",\n audioChannels,\n fps,\n orientation: width >= height ? \"Landscape\" : \"Portrait\",\n location: null, // not supported on web\n };\n } finally {\n resetVideo();\n }\n },\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-video-metadata",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Module to retrieve metadata from a video with Web, Expo and React Native",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -33,15 +33,14 @@
|
|
|
33
33
|
"author": "Hirbod Mirjavadi (https://github.com/hirbod)",
|
|
34
34
|
"license": "MIT",
|
|
35
35
|
"homepage": "https://github.com/hirbod/expo-video-metadata#readme",
|
|
36
|
-
"dependencies": {},
|
|
37
36
|
"devDependencies": {
|
|
38
|
-
"
|
|
39
|
-
"expo-module-scripts": "^3.5.2"
|
|
40
|
-
"expo-modules-core": "^1.12.18"
|
|
37
|
+
"expo": "^52.0.0-preview.4",
|
|
38
|
+
"expo-module-scripts": "^3.5.2"
|
|
41
39
|
},
|
|
42
40
|
"peerDependencies": {
|
|
43
41
|
"expo": "*",
|
|
44
42
|
"react": "*",
|
|
45
43
|
"react-native": "*"
|
|
46
|
-
}
|
|
47
|
-
|
|
44
|
+
},
|
|
45
|
+
"packageManager": "yarn@4.5.1"
|
|
46
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { requireNativeModule } from "expo
|
|
1
|
+
import { requireNativeModule } from "expo";
|
|
2
2
|
export default requireNativeModule("ExpoVideoMetadata");
|
|
@@ -53,27 +53,31 @@ export default {
|
|
|
53
53
|
audioUrl: string,
|
|
54
54
|
options: RequestInit = {}
|
|
55
55
|
): Promise<{ sampleRate: number; numberOfChannels: number }> {
|
|
56
|
-
const audioContext = new (window.AudioContext ||
|
|
57
|
-
(window as any).webkitAudioContext)();
|
|
58
|
-
|
|
59
56
|
try {
|
|
60
57
|
const response = await fetch(audioUrl, options);
|
|
61
58
|
const arrayBuffer = await response.arrayBuffer();
|
|
62
59
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
const audioContext = new (window.AudioContext ||
|
|
61
|
+
(window as any).webkitAudioContext)();
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
|
|
65
|
+
return {
|
|
66
|
+
sampleRate: audioBuffer.sampleRate,
|
|
67
|
+
numberOfChannels: audioBuffer.numberOfChannels,
|
|
68
|
+
};
|
|
69
|
+
} catch (decodeError) {
|
|
70
|
+
console.info("Error decoding audio data (no audio?):", decodeError);
|
|
71
|
+
// If decoding fails, assume no audio
|
|
72
|
+
return { sampleRate: 0, numberOfChannels: 0 };
|
|
73
|
+
} finally {
|
|
74
|
+
await audioContext.close();
|
|
75
|
+
}
|
|
71
76
|
} catch (error) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
await audioContext.close();
|
|
77
|
+
console.info("Error decoding audio data (CORS?):", error);
|
|
78
|
+
|
|
79
|
+
// If any error occurs during the process, return default values silently
|
|
80
|
+
return { sampleRate: 0, numberOfChannels: 0 };
|
|
77
81
|
}
|
|
78
82
|
},
|
|
79
83
|
|
|
@@ -92,7 +96,7 @@ export default {
|
|
|
92
96
|
const contentLength = response.headers.get("Content-Length");
|
|
93
97
|
return contentLength ? parseInt(contentLength, 10) : 0;
|
|
94
98
|
} catch (error) {
|
|
95
|
-
console.
|
|
99
|
+
console.info("Error fetching file size for URL (CORS?):", url, error);
|
|
96
100
|
return 0;
|
|
97
101
|
}
|
|
98
102
|
},
|