Skip to content

Commit

Permalink
Merge pull request #10 from hlxjs/issues/fix-parent-uri-issue
Browse files Browse the repository at this point in the history
Introduce inputDir/outputDir params
  • Loading branch information
kuu committed Jul 30, 2019
2 parents 8412fc0 + f32f985 commit cb59ab6
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 20 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ A writable stream to save HLS playlists/segments as local files
## Features
* Being used with other [`hlx`](https://github.com/hlxjs) objects, it provides a functionality to write every HLS related data (playlist and segments) to your local filesystem.
* It determines the local path for each files based on the `uri` described in the HLS playlist.
* The hostname contained in the `uri` will be ignored (e.g. "https://foo.bar/abc/def.m3u8" is translated into "{rootPath}/abc/def.m3u8")
* The hostname contained in the `uri` will be ignored (e.g. "https://foo.bar/abc/def.m3u8" is translated into "{outputDir}/abc/def.m3u8")
* If the `uri` is a file url, users can specify a root directory (`inputDir`) from which the file should be read (e.g. "file://path/to/abc/def.m3u8", inputDir="/path/to", is translated into "{outputDir}/abc/def.m3u8")

## Install
[![NPM](https://nodei.co/npm/hlx-file-writer.png?mini=true)](https://nodei.co/npm/hlx-file-writer/)
Expand All @@ -27,7 +28,7 @@ const {createTerminator} = require('hlx-terminator')
const src = createReadStream('https://foo.bar/sample.m3u8');
const rewrite = createUrlRewriter();
const save = createWriteStream({
rootPath: '/var/www/media/',
outputDir: '/var/www/media/',
storePlaylist: true
});
const dest = createTerminator();
Expand All @@ -52,7 +53,8 @@ Creates a new `TransformStream` object.
#### options
| Name | Type | Default | Description |
| ----------- | ------ | ------- | --------------------------------- |
| rootPath | string | process.CWD() | The root directory in which all the files are stored |
| inputDir | string | / | The root directory from which all the files are read (This option is only used in case of file urls) |
| outputDir | string | process.CWD() | The root directory to which all the files are written |
| storePlaylist | boolean | false | If true, the playlist files are also stored as local files |

#### return value
Expand Down
24 changes: 17 additions & 7 deletions file.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
const fs = require('fs');
const path = require('path');

const {URL} = require('url');
const debug = require('debug');
const {tryCatch, mkdirP} = require('hlx-util');

function storeData({uri, data}, rootPath) {
const print = debug('hlx-file-writer');

function storeData({uri, parentUri, data}, {inputDir, outputDir}) {
if (!data) {
return Promise.reject(new Error('No segment data'));
}

if (!path.isAbsolute(rootPath)) {
rootPath = path.join(process.cwd(), rootPath);
if (!path.isAbsolute(outputDir)) {
outputDir = path.join(process.cwd(), outputDir);
}

let localPath;

print(`storeData: uri=${uri}, parentUri=${parentUri}, inputDir=${inputDir}, outputDir=${outputDir}`);

if (path.isAbsolute(uri)) {
localPath = path.join(rootPath, uri);
localPath = path.join(outputDir, uri);
} else {
const obj = tryCatch(
() => new URL(uri),
() => new URL(uri, rootPath),
() => new URL(uri, parentUri),
() => null
);
localPath = path.join(rootPath, obj ? obj.pathname : uri);
if (obj) {
localPath = path.join(outputDir, obj.pathname);
} else {
const pathname = path.relative(inputDir, path.join(parentUri, uri));
localPath = path.join(outputDir, pathname);
}
}

// Create directory
Expand Down
10 changes: 5 additions & 5 deletions test/spec/file.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test.cb('file.storeData.Buffer', t => {
const {storeData} = proxyquire('../../file', {fs: mockFs, 'hlx-util': mockUtil});
const spyWriteFile = sinon.spy(mockFs, 'writeFile');

storeData({uri: 'ghi.mp4', data: Buffer.alloc(10)}, '/abc/def/')
storeData({uri: 'ghi.mp4', parentUri: 'http://foo.bar.com/main.m3u8', data: Buffer.alloc(10)}, {inputDir: '/does/not/matter', outputDir: '/abc/def/'})
.then(destPath => {
t.is(destPath, '/abc/def/ghi.mp4');
t.is(spyWriteFile.callCount, 1);
Expand Down Expand Up @@ -51,9 +51,9 @@ test.cb('file.storeData.Buffer.path', t => {
const {storeData} = proxyquire('../../file', {fs: mockFs, 'hlx-util': mockUtil});
const spyWriteFile = sinon.spy(mockFs, 'writeFile');

storeData({uri: '/abc/def/ghi/jkl.mp4', data: Buffer.alloc(10)}, '/path/to/')
storeData({uri: '/abc/def/ghi/jkl.mp4', parentUri: 'file:///path/to/main.m3u8', data: Buffer.alloc(10)}, {inputDir: '/path/to', outputDir: '/root/dir/'})
.then(destPath => {
t.is(destPath, '/path/to/abc/def/ghi/jkl.mp4');
t.is(destPath, '/root/dir/abc/def/ghi/jkl.mp4');
t.is(spyWriteFile.callCount, 1);
t.end();
});
Expand Down Expand Up @@ -92,9 +92,9 @@ test.cb('file.storeData.Stream', t => {
}
};

storeData({uri: 'ghi.mp4', data}, '/abc/def/')
storeData({uri: 'ghi.mp4', parentUri: 'file:///path/to/main.m3u8', data}, {inputDir: '/', outputDir: '/abc/def/'})
.then(destPath => {
t.is(destPath, '/abc/def/ghi.mp4');
t.is(destPath, '/abc/def/path/to/ghi.mp4');
t.is(spyCreateWriteStream.callCount, 1);
t.end();
});
Expand Down
4 changes: 2 additions & 2 deletions test/spec/writable.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ test.cb('writeStream.onlySegments', t => {
const spyWriteFile = sinon.spy(mockFs, 'writeFile');

const src = new MockReadStream();
const fileOutput = new WriteStream({rootPath: '/var/foo/'});
const fileOutput = new WriteStream({outputDir: '/var/foo/'});
const dest = new NullWriteStream();
src.pipe(fileOutput).pipe(dest)
.on('finish', () => {
Expand Down Expand Up @@ -160,7 +160,7 @@ test.cb('writeStream.all', t => {
const spyWriteFile = sinon.spy(mockFs, 'writeFile');

const src = new MockReadStream();
const fileOutput = new WriteStream({rootPath: '/var/foo/', storePlaylist: true});
const fileOutput = new WriteStream({outputDir: '/var/foo/', storePlaylist: true});
const dest = new NullWriteStream();
src.pipe(fileOutput).pipe(dest)
.on('finish', () => {
Expand Down
7 changes: 4 additions & 3 deletions writable.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ const print = debug('hlx-file-writer');
class WriteStream extends stream.Transform {
constructor(options) {
super({objectMode: true});
this.rootPath = options.rootPath || process.cwd();
this.outputDir = options.outputDir || process.cwd();
this.outputDir = options.inputDir || '/';
this.shouldStorePlaylist = Boolean(options.storePlaylist);
}

Expand All @@ -22,10 +23,10 @@ class WriteStream extends stream.Transform {
let params = data;

if (data.type === 'playlist') {
params = {uri: data.uri, data: HLS.stringify(data)};
params = {uri: data.uri, parentUri: data.parentUri, data: HLS.stringify(data)};
}

storeData(params, this.rootPath)
storeData(params, this)
.then(path => {
print(`The data is written to ${path}`);
this.push(data);
Expand Down

0 comments on commit cb59ab6

Please sign in to comment.