UNPKG

skyriver

Version:

SkyRiver Streaming Cloud server-side library for NodeJS

237 lines (197 loc) 5.88 kB
'use strict'; var fmt = require('util') , urlUtil = require('url') , util = require('./util') , API = require('./api') , config = require('./config'); var ORIGIN = config.const.ORIGIN; function Stream(credentials, params) { this.host = config.API_HOST; this.port = config.API_PORT; this.credentials = credentials; this.id = params.id; this.createdAt = params.createdAt; this.updatedAt = params.updatedAt; this.title = params.title; this.hub = params.hub || config.const.DEFAULT_HUB; this.publishKey = params.publishKey; this.record = params.record || 0; this.publishSecurity = params.publishSecurity; if (params.disabled) { this.disabled = params.disabled; } else { this.disabled = false; } this.connect = params.connect || 0; // 推流状态 if (params.profiles == null || params.profiles == 'undefined') { this.profiles = null; } else { this.profiles = params.profiles; } this.hosts = params.hosts; } /** * Stream operations */ Stream.prototype.update = function(options, fn) { API.updateStream(this.credentials, this.id, options, fn); } Stream.prototype.enable = function(fn) { var options = { disabled: false }; API.updateStream(this.credentials, this.id, options, fn); } Stream.prototype.disable = function(fn) { var options = { disabled: true }; API.updateStream(this.credentials, this.id, options, fn); } Stream.prototype.delete = function(fn) { API.deleteStream(this.credentials, this.id, fn); } Stream.prototype.deleteRecord = function(key, fn) { API.deleteRecord(this.credentials, this.id, key, fn); } Stream.prototype.startPull = function(pullUrl, notifyUrl, fn) { var options = { action: 'start', pullUrl: pullUrl, notifyUrl: notifyUrl }; API.noftifyPullStream(this.credentials, this.id, options, fn); } Stream.prototype.stopPull = function(notifyUrl, fn) { var options = { action: 'stop', notifyUrl: notifyUrl }; API.noftifyPullStream(this.credentials, this.id, options, fn); } Stream.prototype.status = function(fn) { API.getStreamStatus(this.credentials, this.id, fn); } /** * 向服务请求实际播放地址 * @param fn */ Stream.prototype.getPlayUrl = function(fn) { var playUrl = this.playUrl(); var hosts = fmt.format('%s:%s/v1', this.host, this.port); var path = playUrl.replace(hosts, ''); API.getPlayURL(this.credentials, path, fn); } /** * 向天河服务器重新请求推流服务器地址 * @param fn */ Stream.prototype.getPublishUrl = function(fn) { API.getReceiver(this.credentials, this.id, fn); } /** * 向服务请求实际点播地址 * @param fn */ Stream.prototype.getVodUrl = function(options, fn) { var vodUrl = this.vodUrl(options); var hosts = fmt.format('%s:%s/v1', this.host, this.port); var path = vodUrl.replace(hosts, ''); API.getVodURL(this.credentials, path, fn); } Stream.prototype.segments = function(options, fn) { API.getStreamSegments(this.credentials, this.id, options, fn); } Stream.prototype.records = function(fn) { API.getRecords(this.credentials, this.id, fn); } Stream.prototype.snapshot = function(name, format, options, fn) { API.snapshotStream(this.credentials, this.id, name, format, options, fn); } function replacer(key, value) { if (key == 'credentials') { return undefined; } else if (key == 'play') { return undefined; } else { return value; } } Stream.prototype.toJSONString = function() { return JSON.stringify(this, replacer); } Stream.prototype.saveAs = function(key, name, format, options, fn) { API.saveStreamAs(this.credentials, this.id, key, name, format, options, fn); } /** * URL generators */ Stream.prototype.publishServerUrl = function() { return fmt.format('%s', this.hosts.playback); }; Stream.prototype.rtmpPublishUrl = function() { var url = ''; var rtmpPublishHost = this.hosts.publish; switch (this.publishSecurity) { case 'static': url = this._staticUrl(rtmpPublishHost); break; case 'dynamic': url = this._dynamicUrl(rtmpPublishHost); break; } return url; } /** * 生成请求播放地址接口 */ Stream.prototype.playUrl = function() { var pullUrl = fmt.format('%s:%s/v1/streams/%s/playurl', this.host, this.port, this.id); return this._withToken(pullUrl); } /** * 生成请求点播地址接口 */ Stream.prototype.vodUrl = function(options) { var vodUrl = fmt.format('%s:%s/v1/streams/%s/vodurl', this.host, this.port, this.id); vodUrl = this._withToken(vodUrl); if (options && options.name) { vodUrl += '&name=' + options.name; } return vodUrl; } Stream.prototype._withToken = function(parmsUrl) { var url = ''; switch (this.publishSecurity) { case 'static': url = fmt.format('%s?nonce=%d&token=%s', parmsUrl, this._nonceValue(), this.publishKey); break; case 'dynamic': url = fmt.format('%s?nonce=%d&token=%s', parmsUrl, this._nonceValue(), this._token(parmsUrl)); break; } return url; } Stream.prototype._staticUrl = function(rtmpPublishHost) { var url = fmt.format('rtmp://%s/live/%s?nonce=%d&token=%s', rtmpPublishHost, this.id, this._nonceValue(), this.publishKey); return url; } Stream.prototype._dynamicUrl = function(rtmpPublishHost) { this.nonce = 0; var url = fmt.format('rtmp://%s/live/?nonce=%d&token=%s', rtmpPublishHost, this._nonceValue(), this._token(rtmpPublishHost)); return url; } Stream.prototype._nonceValue = function() { if (!this.nonce) { this.nonce = Date.now() / 1000 | 0; } return parseInt(this.nonce, 10); } Stream.prototype._token = function(rtmpPublishHost) { var urlObject = urlUtil.parse(rtmpPublishHost); var path = urlObject.path + '?nonce=' + this.nonce; var digest = util.hmacSha1(path, this.publishKey); var token = util.base64ToUrlSafe(digest); return token; } module.exports = Stream;