Node.js server to convert DASH video stream manifests to HLS
Summary of Behavior
- runs an HTTP(S) server
- each inbound request includes:
- required in URL path:
- base64 encoded URL for a DASH manifest
- optional in querystring parameters:
&dump=1
- outputs a dump of JSON data
- which is mainly useful for me during development
&VOD=1
- HLS master manifest forwards this querystring parameter in URLs for all HLS child manifests
- HLS child manifests include:
- prefix:
#EXT-X-PLAYLIST-TYPE:VOD
- suffix:
#EXT-X-ENDLIST
- this overrides the default behavior, which is to determine VOD when the DASH manifest does not include:
MPD@type="dynamic"
&playlist=bandwidth
- outputs an HLS child manifest for the given playlist (as identified by its integer bandwidth)
- media group: VIDEO
&group_type=(AUDIO|SUBTITLES)&group_id=id&group_lang=lang&group_index=0
- outputs an HLS child manifest for the given media group
- media group: AUDIO|SUBTITLES
- [default]
- outputs the HSL master manifest
- includes URLs to access all HLS child manifests
- when each inbound request is received:
- the base64 encoded DASH manifest URL is used as a key to lookup whether a parsed data structure representing the DASH manifest is temporarily held in a cache
- if not, then:
- download the DASH manifest
- several command-line options are available to configure HTTP requests made to external servers
- parse its contents (using mpd-parser library)
- add the parsed DASH data structure to the cache
- continue..
- the querystring parameters are used to determine which HLS manifest to output
- the parsed DASH data structure is used to produce this result
Installation and Usage: Globally
How to: Install:
npm install --global "@warren-bank/dash-to-hls"
How to: Run the server(s):
dash-to-hls [--help] [--version] [--tls] [--host <ip_address>] [--port <number>] [--req-headers <filepath>] [--origin <header>] [--referer <header>] [--useragent <header>] [--header <name=value>] [--req-options <filepath>] [--req-secure-honor-server-cipher-order] [--req-secure-ciphers <string>] [--req-secure-protocol <string>] [--req-secure-curve <string>] [-v <number>] [--acl-whitelist <ip_address_list>]
Examples:
-
print help
dash-to-hls --help
-
print version
dash-to-hls --version
-
start HTTP server at default host:port
dash-to-hls
-
start HTTP server at default host and specific port
dash-to-hls --port "8080"
-
start HTTP server at specific host:port
dash-to-hls --host "192.168.0.100" --port "8080"
-
start HTTPS server at default host:port
dash-to-hls --tls
-
start HTTPS server at specific host:port
dash-to-hls --tls --host "192.168.0.100" --port "8081"
-
start HTTPS server at default host:port and send specific HTTP headers
dash-to-hls --tls --req-headers "/path/to/request/headers.json"
Options:
- --tls is a flag to start HTTPS server, rather than HTTP
- --host must be an IP address of the server
- ex:
192.168.0.100
- used to generate self-referencing URLs in the master HLS manifest to query each child manifest
- when this option is not specified:
- the list of available network addresses is determined
- if there are none, 'localhost' is used silently
- if there is only a single address on the LAN, it is used silently
- if there are multiple addresses:
- they are listed
- a prompt asks the user to choose (the numeric index) of one
- --port is the port number that the server listens on
- ex:
8080
- used to generate self-referencing URLs in the master HLS manifest to query each child manifest
- when this option is not specified:
- HTTP server binds to:
80
- HTTPS server binds to:
443
- --req-headers is the filepath to a JSON data Object containing key:value pairs
- each key is the name of an HTTP header to send in in every outbound request
- --origin is the value of the corresponding HTTP request header
- --referer is the value of the corresponding HTTP request header
- --useragent is the value of the corresponding HTTP request header
- --header is a single name:value pair
- this option can be used multiple times to include several HTTP request headers
- the pair can be written:
- "name: value"
- "name=value"
- "name = value"
- --req-options is the filepath to a JSON data Object
- exposes the options Object passed to low-level network request APIs:
- advanced https request options:
- context of the secure request is obtained by passing the request options Object to:
tls.createSecureContext(options)
- configuration for the context of the secure request can be merged with the request options Object
- configuration keys of particular interest:
honorCipherOrder
ciphers
secureProtocol
ecdhCurve
- default value:
tls.DEFAULT_ECDH_CURVE
- the exact value depends on the version of node
- most commonly:
- older versions of node:
"prime256v1"
- newer versions of node:
"auto"
- --req-secure-honor-server-cipher-order is a flag to set the following key in the request options Object to configure the context for secure https requests:
- --req-secure-ciphers is the value to assign to the following key in the request options Object to configure the context for secure https requests:
- --req-secure-protocol is the value to assign to the following key in the request options Object to configure the context for secure https requests:
- --req-secure-curve is the value to assign to the following key in the request options Object to configure the context for secure https requests:
- -v sets logging verbosity level:
-1
:
0
(default):
1
:
- show an informative amount of information
2
:
3
:
- show an enhanced technical trace (useful while debugging unexpected behavior)
- --acl-whitelist restricts server access to clients at IP addresses in whitelist
- ex:
"192.168.1.100,192.168.1.101,192.168.1.102"
Installation and Usage: Working with a Local git
Repo
How to: Install:
git clone "https://github.com/warren-bank/DASH-to-HLS.git"
cd "DASH-to-HLS"
npm install
How to: Run the server(s):
npm start [-- [--help] [--version] [--tls] [--host <ip_address>] [--port <number>] [--req-headers <filepath>] [--origin <header>] [--referer <header>] [--useragent <header>] [--header <name=value>] [--req-options <filepath>] [--req-secure-honor-server-cipher-order] [--req-secure-ciphers <string>] [--req-secure-protocol <string>] [--req-secure-curve <string>] [-v <number>] ]
npm run sudo [-- [--help] [--version] [--tls] [--host <ip_address>] [--port <number>] [--req-headers <filepath>] [--origin <header>] [--referer <header>] [--useragent <header>] [--header <name=value>] [--req-options <filepath>] [--req-secure-honor-server-cipher-order] [--req-secure-ciphers <string>] [--req-secure-protocol <string>] [--req-secure-curve <string>] [-v <number>] ]
Examples:
-
print help
npm start -- --help
-
start HTTP server at specific host:port
npm start -- --host "192.168.0.100" --port "8080"
-
start HTTPS server at specific host:port
npm start -- --host "192.168.0.100" --port "8081" --tls
-
start HTTP server at default host:port with escalated privilege
npm run sudo -- --port "80"
-
start HTTPS server at default host:port with escalated privilege
npm run sudo -- --port "443" --tls
-
start HTTP server at specific port and send custom request headers
headers_file="${TMPDIR}/headers.json"
echo '{"Origin" : "http://XXX:80", "Referer": "http://XXX:80/page.html"}' > "$headers_file"
npm start -- --port "8080" --req-headers "$headers_file"
- start HTTPS server at specific port and send custom request headers
headers_file="${TMPDIR}/headers.json"
echo '{"Origin" : "http://XXX:80", "Referer": "http://XXX:80/page.html"}' > "$headers_file"
npm start -- --port "8081" --req-headers "$headers_file" --tls -v 1
- start HTTPS server at specific port and send custom request headers
h_origin='http://XXX:80'
h_referer='http://XXX:80/page.html'
h_useragent='Chromium'
h_custom_1='X-Foo: 123'
h_custom_2='X-Bar: baz'
npm start -- --port "8081" --origin "$h_origin" --referer "$h_referer" --useragent "$h_useragent" --header "$h_custom_1" --header "$h_custom_2" --tls -v 1
Options:
Legal: