智能照明系统APP-本地串口
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
LightingSystemApp-serial/.svn/pristine/52/52dc2355ebb2108ab52d7f2b2c5...

189 lines
3.7 KiB

import {
onMethod,
invokeMethod
} from '../../platform'
const eventNames = [
'canplay',
'play',
'pause',
'stop',
'ended',
'timeUpdate',
'error',
'waiting',
'seeking',
'seeked'
]
const props = [
{
name: 'src',
cache: true
},
{
name: 'startTime',
default: 0,
cache: true
},
{
name: 'autoplay',
default: false,
cache: true
},
{
name: 'loop',
default: false,
cache: true
},
{
name: 'obeyMuteSwitch',
default: true,
readonly: true,
cache: true
},
{
name: 'duration',
readonly: true
},
{
name: 'currentTime',
readonly: true
},
{
name: 'paused',
readonly: true
},
{
name: 'buffered',
readonly: true
},
{
name: 'volume'
}
]
class InnerAudioContext {
constructor (id) {
this.id = id
this._callbacks = {}
this._options = {}
eventNames.forEach(name => {
this._callbacks[name.toLowerCase()] = []
})
props.forEach(item => {
const name = item.name
const data = {
get () {
const result = item.cache ? this._options : invokeMethod('getAudioState', {
audioId: this.id
})
const value = name in result ? result[name] : item.default
return typeof value === 'number' && name !== 'volume' ? value / 1e3 : value
}
}
if (!item.readonly) {
data.set = function (value) {
this._options[name] = value
invokeMethod('setAudioState', Object.assign({}, this._options, {
audioId: this.id
}))
}
}
Object.defineProperty(this, name, data)
})
}
play () {
this._operate('play')
}
pause () {
this._operate('pause')
}
stop () {
this._operate('stop')
}
seek (position) {
this._operate('seek', {
currentTime: position * 1e3
})
}
destroy () {
clearInterval(this.__timing)
invokeMethod('destroyAudioInstance', {
audioId: this.id
})
delete innerAudioContexts[this.id]
}
_operate (type, options) {
invokeMethod('operateAudio', Object.assign({}, options, {
audioId: this.id,
operationType: type
}))
}
}
eventNames.forEach(item => {
const name = item[0].toUpperCase() + item.substr(1)
item = item.toLowerCase()
InnerAudioContext.prototype[`on${name}`] = function (callback) {
this._callbacks[item].push(callback)
}
InnerAudioContext.prototype[`off${name}`] = function (callback) {
const callbacks = this._callbacks[item]
const index = callbacks.indexOf(callback)
if (index >= 0) {
callbacks.splice(index, 1)
}
}
})
function emit (audio, state, errMsg, errCode) {
audio._callbacks[state].forEach(callback => {
if (typeof callback === 'function') {
callback(state === 'error' ? {
errMsg,
errCode
} : {})
}
})
}
onMethod('onAudioStateChange', ({
state,
audioId,
errMsg,
errCode
}) => {
const audio = innerAudioContexts[audioId]
if (audio) {
emit(audio, state, errMsg, errCode)
if (state === 'play') {
const oldCurrentTime = audio.currentTime
audio.__timing = setInterval(() => {
const currentTime = audio.currentTime
if (currentTime !== oldCurrentTime) {
emit(audio, 'timeupdate')
}
}, 200)
} else if (state === 'pause' || state === 'stop' || state === 'error') {
clearInterval(audio.__timing)
}
}
})
const innerAudioContexts = Object.create(null)
export function createInnerAudioContext () {
const {
audioId
} = invokeMethod('createAudioInstance')
const innerAudioContext = new InnerAudioContext(audioId)
innerAudioContexts[audioId] = innerAudioContext
return innerAudioContext
}