forked from little-core-labs/little-media-box
-
Notifications
You must be signed in to change notification settings - Fork 1
/
asset.js
113 lines (101 loc) · 2.7 KB
/
asset.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
const extensions = require('./extensions')
const { Source } = require('./source')
const through = require('through2')
const getUri = require('get-uri')
const debug = require('debug')('little-media-box:asset')
const ready = require('nanoresource-ready')
const path = require('path')
const pump = require('pump')
const uuid = require('uuid/v4')
const url = require('url')
const fs = require('fs')
const { head } = require('simple-get')
/**
* The `Asset` class represents a container for an external asset
* that has semantic associations with other objects.
* @public
* @class
* @extends nanoresource
*/
class Asset extends Source {
/**
* `Asset` class constructor.
* @param {String} uri
* @param {?(Object)} opts
* @param {?(String)} opts.id
* @param {?(String)} opts.cwd
* @param {?(String)} opts.type
* @param {?(Array<String>)} opts.associations
*/
constructor(uri, opts) {
super()
if (!opts || 'object' !== typeof opts) {
opts = {}
}
this.id = opts.id || uuid()
this.uri = uri
this.cwd = opts.cwd || process.cwd()
this.type = opts.type || extensions.typeof(path.extname(this.uri))
this.byteLength = 0
this.associations = Array.from(opts.associations || [])
}
/**
* Implements the abstract `_open()` method for `nanoresource`
* Opens the asset source stream and initializes internal state.
* @protected
* @param {Function} callback
*/
_open(callback) {
const uri = url.parse(this.uri)
if (/https?:/.test(uri.protocol)) {
head(this.uri, (err, res) => {
if (err) { return callback(err) }
this.byteLength = parseInt(res.headers['content-length'])
callback(null)
})
} else {
const pathname = path.resolve(this.cwd, uri.path)
fs.stat(pathname, (err, stats) => {
if (err) { return callback(err) }
this.uri = `file://${pathname}`
this.byteLength = stats.size
callback(null)
})
}
}
/**
* Wait for asset to be ready (opened) calling `callback()`
* when it is.
* @param {Function}
*/
ready(callback) {
ready(this, callback)
}
/**
* Creates a read stream for the asset URI.
* @param {?(Object)} opts
* @return {Stream}
*/
createReadStream(opts) {
if (!opts || 'object' !== typeof opts) {
opts = {}
}
const readStream = through()
const { uri } = this
getUri(uri, onstream)
return readStream
function onstream(err, sourceStream) {
if (err) { return readStream.emit('error', err) }
pump(sourceStream, readStream, onpump)
}
function onpump(err) {
if (err) { return readStream.emit('error', err) }
}
}
}
/**
* Module exports.
*/
module.exports = {
Asset
}