diff --git a/.gitignore b/.gitignore index 816ae80..b7cad50 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ dist node_modules tmp +**/*.js +package-lock.json \ No newline at end of file diff --git a/README.md b/README.md index 6ed973a..2e98cd8 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,11 @@ Node implementation of [MediaArea's MediaInfo](https://mediaarea.net/en/MediaInfo) WebAssembly binary. ## Install - ```sh $ npm install --save node-mediainfo ``` ## Usage - ```ts // Using ES6 imports import mediainfo from 'node-mediainfo'; @@ -20,7 +18,7 @@ import mediainfo from 'node-mediainfo'; const mediainfo = require('node-mediainfo'); async function main() { - const result = await mediainfo('path to media file'); + const result = await mediainfo(''); console.log(result); } @@ -32,6 +30,4 @@ main(); - Package: [npmjs.com/package/node-mediainfo](https://www.npmjs.com/package/node-mediainfo) ## License - - This package uses [MediaInfo](http://mediaarea.net/MediaInfo) library, Copyright (c) 2002-2019 [MediaArea.net SARL](mailto:Info@MediaArea.net) diff --git a/examples/stream.ts b/examples/stream.ts index ecd9c47..38c2e54 100644 --- a/examples/stream.ts +++ b/examples/stream.ts @@ -1,9 +1,11 @@ import mediainfo from '../src'; -mediainfo('').then( +mediainfo('http://dl5.webmfiles.org/big-buck-bunny_trailer.webm').then( (response) => { console.log(JSON.stringify( response, null, 2, )); }, -); +).catch((err) => { + console.error(err); +}); diff --git a/package.json b/package.json index f82da17..50ea324 100644 --- a/package.json +++ b/package.json @@ -26,5 +26,9 @@ "build": "npm run types && tsc", "prepare": "npm run build", "types": "tsc --outDir tmp src/build.ts --lib es2017 && node tmp/build" + }, + "dependencies": { + "@types/request": "^2.48.4", + "request": "^2.88.0" } } diff --git a/src/index.ts b/src/index.ts index 491ffef..d1c981e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ -import { PathLike, createReadStream, statSync } from 'fs'; +import { PathLike, createReadStream, stat } from 'fs'; +import Request = require('request'); import { Audio, General, Image, Menu, Other, Text, Video, } from './types'; @@ -26,39 +27,77 @@ async function Init() { }); } -export = async function MediaInfo(path: PathLike): Promise { - if (!MediaInfoModule) { - await Init(); +async function GetSize(path: PathLike, headers = {}) { + return new Promise((resolve, reject) => { + if (path.toString().indexOf('http') === 0) { + return Request({ + method: 'HEAD', + url: path.toString(), + headers + }).on('response', (res: any) => { + resolve(parseInt(res.headers['content-length'], 10) || 0); + }).on('error', (err: Error) => { + reject(err); + }) + } + stat(path, (err, stats) => { + if (err) { + return reject(err); + } + resolve(stats.size || 0) + }) + }) +} + +function GetStream(path: PathLike, start = 0, length = -1, headers = {}): any { + if (path.toString().indexOf('http') === 0) { + return Request({ + url: path.toString(), + headers: { + ...headers, + Range: `bytes=${start}-${length}` + } + }) } - return new Promise((resolve) => { - const stream = createReadStream(path, { - highWaterMark: 1024 * 1024, - }); - const { size } = statSync(path); + return createReadStream(path, { + highWaterMark: length, + start, + }); +} + +export default function MediaInfo(path: PathLike, headers = {}): Promise { + return new Promise(async (resolve) => { + + if (!MediaInfoModule) { + await Init(); + } + + let seekTo: number; + + const stream = GetStream(path, 0, 1024 * 1024, headers); + const size = await GetSize(path); const MI = new MediaInfoModule.MediaInfo(); MI.Open_Buffer_Init(size, 0); - let seekTo: number; - stream.on('data', (chunk) => { + stream.on('data', (chunk: any) => { MI.Open_Buffer_Continue(chunk); seekTo = MI.Open_Buffer_Continue_Goto_Get(); // console.log('SeekTo', seekTo); if (seekTo !== -1) { MI.Open_Buffer_Init(size, seekTo); - stream.close(); + if (typeof (stream.close) !== 'undefined') { + stream.close(); + } } }); stream.on('close', () => { - const newstream = createReadStream(path, { - highWaterMark: 1024 * 1024, - start: seekTo, - }); + const newstream = GetStream(path, seekTo, 1024 * 1024, headers); - newstream.on('data', (chunk) => { + newstream.on('data', (chunk: any) => { MI.Open_Buffer_Continue(chunk); seekTo = MI.Open_Buffer_Continue_Goto_Get(); // console.log('SeekTo', seekTo);