Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
ChenYFan_OHHH
uni-app
提交
2c800299
U
uni-app
项目概览
ChenYFan_OHHH
/
uni-app
与 Fork 源项目一致
Fork自
DCloud / uni-app
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2c800299
编写于
6月 24, 2021
作者:
D
DCloud_LXH
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(App): BackgroundAudioManager
上级
a391cdaf
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
454 addition
and
0 deletion
+454
-0
packages/uni-api/src/index.ts
packages/uni-api/src/index.ts
+1
-0
packages/uni-api/src/protocols/context/backgroundAudio.ts
packages/uni-api/src/protocols/context/backgroundAudio.ts
+2
-0
packages/uni-app-plus/src/service/api/context/backgroundAudio.ts
...s/uni-app-plus/src/service/api/context/backgroundAudio.ts
+449
-0
packages/uni-app-plus/src/service/api/index.ts
packages/uni-app-plus/src/service/api/index.ts
+2
-0
未找到文件。
packages/uni-api/src/index.ts
浏览文件 @
2c800299
...
...
@@ -21,6 +21,7 @@ export * from './protocols/base/canIUse'
export
*
from
'
./protocols/context/context
'
export
*
from
'
./protocols/context/canvas
'
export
*
from
'
./protocols/context/backgroundAudio
'
export
*
from
'
./protocols/device/makePhoneCall
'
export
*
from
'
./protocols/device/setClipboardData
'
...
...
packages/uni-api/src/protocols/context/backgroundAudio.ts
0 → 100644
浏览文件 @
2c800299
export
const
API_BACKGROUND_AUDIO
=
'
getBackgroundAudioManager
'
export
type
API_TYPE_BACKGROUND_AUDIO
=
typeof
uni
.
getBackgroundAudioManager
packages/uni-app-plus/src/service/api/context/backgroundAudio.ts
0 → 100644
浏览文件 @
2c800299
import
{
extend
}
from
'
@vue/shared
'
import
{
defineSyncApi
,
API_BACKGROUND_AUDIO
,
API_TYPE_BACKGROUND_AUDIO
,
}
from
'
@dcloudio/uni-api
'
import
{
once
}
from
'
@dcloudio/uni-shared
'
import
{
getRealPath
}
from
'
@dcloudio/uni-platform
'
type
eventNames
=
|
'
canplay
'
|
'
play
'
|
'
pause
'
|
'
stop
'
|
'
ended
'
|
'
timeUpdate
'
|
'
prev
'
|
'
next
'
|
'
error
'
|
'
waiting
'
type
onEventNames
=
|
'
onNext
'
|
'
onPrev
'
|
'
onWaiting
'
|
'
onTimeUpdate
'
|
'
onEnded
'
|
'
onStop
'
|
'
onPause
'
|
'
onPlay
'
|
'
onCanplay
'
|
'
onError
'
type
AudioEvents
=
|
'
canplay
'
|
'
play
'
|
'
pause
'
|
'
stop
'
|
'
ended
'
|
'
error
'
|
'
waiting
'
|
'
seeking
'
|
'
seeked
'
type
Events
=
'
play
'
|
'
pause
'
|
'
ended
'
|
'
stop
'
|
'
canplay
'
type
Audio
=
PlusAudioAudioPlayer
&
{
src
?:
string
title
?:
string
epname
?:
string
singer
?:
string
coverImgUrl
?:
string
webUrl
?:
string
startTime
?:
number
isStopped
?:
boolean
}
const
eventNames
:
eventNames
[]
=
[
'
canplay
'
,
'
play
'
,
'
pause
'
,
'
stop
'
,
'
ended
'
,
'
timeUpdate
'
,
'
prev
'
,
'
next
'
,
'
error
'
,
'
waiting
'
,
]
const
callbacks
:
Record
<
eventNames
,
Function
[]
>
=
{
canplay
:
[],
play
:
[],
pause
:
[],
stop
:
[],
ended
:
[],
timeUpdate
:
[],
prev
:
[],
next
:
[],
error
:
[],
waiting
:
[],
}
let
audio
:
Audio
let
timeUpdateTimer
:
number
|
null
=
null
const
TIME_UPDATE
=
250
const
events
:
Events
[]
=
[
'
play
'
,
'
pause
'
,
'
ended
'
,
'
stop
'
,
'
canplay
'
]
function
startTimeUpdateTimer
()
{
stopTimeUpdateTimer
()
timeUpdateTimer
=
setInterval
(()
=>
{
onBackgroundAudioStateChange
({
state
:
'
timeUpdate
'
})
},
TIME_UPDATE
)
}
function
stopTimeUpdateTimer
()
{
if
(
timeUpdateTimer
!==
null
)
{
clearInterval
(
timeUpdateTimer
)
}
}
function
initMusic
()
{
if
(
audio
)
{
return
}
const
publish
=
UniServiceJSBridge
.
invokeOnCallback
audio
=
plus
.
audio
.
createPlayer
({
autoplay
:
true
,
backgroundControl
:
true
,
})
audio
.
src
=
audio
.
title
=
audio
.
epname
=
audio
.
singer
=
audio
.
coverImgUrl
=
audio
.
webUrl
=
''
audio
.
startTime
=
0
events
.
forEach
((
event
)
=>
{
audio
.
addEventListener
(
event
as
AudioEvents
,
()
=>
{
// 添加 isStopped 属性是为了解决 安卓设备停止播放后获取播放进度不正确的问题
if
(
event
===
'
play
'
)
{
audio
.
isStopped
=
false
startTimeUpdateTimer
()
}
else
if
(
event
===
'
stop
'
)
{
audio
.
isStopped
=
true
}
if
(
event
===
'
pause
'
||
event
===
'
ended
'
||
event
===
'
stop
'
)
{
stopTimeUpdateTimer
()
}
const
eventName
=
`onMusic
${
event
[
0
].
toUpperCase
()
+
event
.
substr
(
1
)}
`
publish
(
eventName
,
{
dataUrl
:
audio
.
src
,
errMsg
:
`
${
eventName
}
:ok`
,
})
onBackgroundAudioStateChange
({
state
:
event
,
dataUrl
:
audio
.
src
,
})
})
})
audio
.
addEventListener
(
'
waiting
'
,
()
=>
{
stopTimeUpdateTimer
()
onBackgroundAudioStateChange
({
state
:
'
waiting
'
,
dataUrl
:
audio
.
src
,
})
})
audio
.
addEventListener
(
'
error
'
,
(
err
)
=>
{
stopTimeUpdateTimer
()
publish
(
'
onMusicError
'
,
{
dataUrl
:
audio
.
src
,
errMsg
:
'
Error:
'
+
err
.
message
,
})
onBackgroundAudioStateChange
({
state
:
'
error
'
,
dataUrl
:
audio
.
src
,
errMsg
:
err
.
message
,
errCode
:
err
.
code
,
})
})
// @ts-ignore
audio
.
addEventListener
(
'
prev
'
,
()
=>
publish
(
'
onBackgroundAudioPrev
'
))
// @ts-ignore
audio
.
addEventListener
(
'
next
'
,
()
=>
publish
(
'
onBackgroundAudioNext
'
))
}
function
getBackgroundAudioState
()
{
let
data
=
{
duration
:
0
,
currentTime
:
0
,
paused
:
false
,
src
:
''
,
buffered
:
0
,
title
:
''
,
epname
:
''
,
singer
:
''
,
coverImgUrl
:
''
,
webUrl
:
''
,
startTime
:
0
,
errMsg
:
'
getBackgroundAudioState:ok
'
,
}
if
(
audio
)
{
const
newData
=
{
duration
:
audio
.
getDuration
()
||
0
,
currentTime
:
audio
.
isStopped
?
0
:
audio
.
getPosition
(),
paused
:
audio
.
isPaused
(),
src
:
audio
.
src
,
buffered
:
audio
.
getBuffered
(),
title
:
audio
.
title
,
epname
:
audio
.
epname
,
singer
:
audio
.
singer
,
coverImgUrl
:
audio
.
coverImgUrl
,
webUrl
:
audio
.
webUrl
,
startTime
:
audio
.
startTime
,
}
data
=
extend
(
data
,
newData
)
}
return
data
}
function
setMusicState
(
args
:
Partial
<
Audio
>
)
{
initMusic
()
const
props
=
[
'
src
'
,
'
startTime
'
,
'
coverImgUrl
'
,
'
webUrl
'
,
'
singer
'
,
'
epname
'
,
'
title
'
,
]
const
style
=
{}
Object
.
keys
(
args
).
forEach
((
key
)
=>
{
if
(
props
.
indexOf
(
key
)
>=
0
)
{
let
val
=
(
args
as
any
)[
key
]
if
(
key
===
props
[
0
]
&&
val
)
{
val
=
getRealPath
(
val
as
string
)
}
;(
audio
as
any
)[
key
]
=
(
style
as
any
)[
key
]
=
val
}
})
audio
.
setStyles
(
style
)
}
function
operateMusicPlayer
({
operationType
,
src
,
position
,
api
=
'
operateMusicPlayer
'
,
title
,
coverImgUrl
,
}:
{
operationType
:
string
position
:
number
api
:
string
src
?:
string
title
?:
string
coverImgUrl
?:
string
})
{
var
operationTypes
=
[
'
resume
'
,
'
pause
'
,
'
stop
'
]
if
(
operationTypes
.
indexOf
(
operationType
)
>
0
)
{
audio
&&
(
audio
as
any
)[
operationType
]()
}
else
if
(
operationType
===
'
play
'
)
{
setMusicState
({
src
,
startTime
:
position
,
title
,
coverImgUrl
,
})
audio
.
play
()
}
else
if
(
operationType
===
'
seek
'
)
{
audio
&&
audio
.
seekTo
(
position
)
}
return
{
errMsg
:
`
${
api
}
:ok`
,
}
}
function
operateBackgroundAudio
({
operationType
,
src
,
startTime
,
currentTime
,
}:
{
operationType
:
string
src
?:
string
startTime
?:
number
currentTime
?:
number
})
{
return
operateMusicPlayer
({
operationType
,
src
,
position
:
startTime
||
currentTime
||
0
,
api
:
'
operateBackgroundAudio
'
,
})
}
function
onBackgroundAudioStateChange
({
state
,
errMsg
,
errCode
,
dataUrl
,
}:
{
state
:
eventNames
errMsg
?:
string
errCode
?:
number
dataUrl
?:
string
})
{
callbacks
[
state
].
forEach
((
callback
)
=>
{
if
(
typeof
callback
===
'
function
'
)
{
callback
(
state
===
'
error
'
?
{
errMsg
,
errCode
,
}
:
{}
)
}
})
}
const
onInitBackgroundAudioManager
=
/*#__PURE__*/
once
(()
=>
{
eventNames
.
forEach
((
item
)
=>
{
const
name
=
item
[
0
].
toUpperCase
()
+
item
.
substr
(
1
)
BackgroundAudioManager
.
prototype
[
`on
${
name
}
`
as
onEventNames
]
=
function
(
callback
:
Function
)
{
callbacks
[
item
].
push
(
callback
)
}
})
})
const
props
=
[
{
name
:
'
duration
'
,
readonly
:
true
,
},
{
name
:
'
currentTime
'
,
readonly
:
true
,
},
{
name
:
'
paused
'
,
readonly
:
true
,
},
{
name
:
'
src
'
,
cache
:
true
,
},
{
name
:
'
startTime
'
,
default
:
0
,
cache
:
true
,
},
{
name
:
'
buffered
'
,
readonly
:
true
,
},
{
name
:
'
title
'
,
cache
:
true
,
},
{
name
:
'
epname
'
,
cache
:
true
,
},
{
name
:
'
singer
'
,
cache
:
true
,
},
{
name
:
'
coverImgUrl
'
,
cache
:
true
,
},
{
name
:
'
webUrl
'
,
cache
:
true
,
},
{
name
:
'
protocol
'
,
readonly
:
true
,
default
:
'
http
'
,
},
]
class
BackgroundAudioManager
implements
UniApp
.
BackgroundAudioManager
{
'
duration
'
:
UniApp
.
BackgroundAudioManager
[
'
duration
'
]
'
startTime
'
:
UniApp
.
BackgroundAudioManager
[
'
startTime
'
]
'
currentTime
'
:
UniApp
.
BackgroundAudioManager
[
'
currentTime
'
]
'
paused
'
:
UniApp
.
BackgroundAudioManager
[
'
paused
'
]
'
src
'
:
UniApp
.
BackgroundAudioManager
[
'
src
'
]
'
buffered
'
:
UniApp
.
BackgroundAudioManager
[
'
buffered
'
]
'
title
'
:
UniApp
.
BackgroundAudioManager
[
'
title
'
]
'
epname
'
:
UniApp
.
BackgroundAudioManager
[
'
epname
'
]
'
singer
'
:
UniApp
.
BackgroundAudioManager
[
'
singer
'
]
'
coverImgUrl
'
:
UniApp
.
BackgroundAudioManager
[
'
coverImgUrl
'
]
'
webUrl
'
:
UniApp
.
BackgroundAudioManager
[
'
webUrl
'
]
'
protocol
'
:
UniApp
.
BackgroundAudioManager
[
'
webUrl
'
]
_options
:
Data
constructor
()
{
this
.
_options
=
{}
props
.
forEach
((
item
)
=>
{
const
name
=
item
.
name
Object
.
defineProperty
(
this
,
name
,
{
get
:
()
=>
{
const
result
=
item
.
cache
?
this
.
_options
:
getBackgroundAudioState
()
return
name
in
result
?
result
[
name
]
:
item
.
default
},
set
:
item
.
readonly
?
undefined
:
(
value
)
=>
{
this
.
_options
[
name
]
=
value
setMusicState
(
this
.
_options
as
any
)
},
})
})
onInitBackgroundAudioManager
()
}
play
()
{
this
.
_operate
(
'
play
'
)
}
pause
()
{
this
.
_operate
(
'
pause
'
)
}
stop
()
{
this
.
_operate
(
'
stop
'
)
}
seek
(
position
:
number
)
{
this
.
_operate
(
'
seek
'
,
{
currentTime
:
position
,
})
}
_operate
(
type
:
string
,
options
?:
Data
)
{
operateBackgroundAudio
(
extend
({},
options
,
{
operationType
:
type
,
})
)
}
'
onCanplay
'
:
UniApp
.
BackgroundAudioManager
[
'
onCanplay
'
]
'
onPlay
'
:
UniApp
.
BackgroundAudioManager
[
'
onPlay
'
]
'
onPause
'
:
UniApp
.
BackgroundAudioManager
[
'
onPause
'
]
'
onStop
'
:
UniApp
.
BackgroundAudioManager
[
'
onStop
'
]
'
onEnded
'
:
UniApp
.
BackgroundAudioManager
[
'
onEnded
'
]
'
onTimeUpdate
'
:
UniApp
.
BackgroundAudioManager
[
'
onTimeUpdate
'
]
'
onWaiting
'
:
UniApp
.
BackgroundAudioManager
[
'
onWaiting
'
]
'
onPrev
'
:
UniApp
.
BackgroundAudioManager
[
'
onPrev
'
]
'
onNext
'
:
UniApp
.
BackgroundAudioManager
[
'
onNext
'
]
'
onError
'
:
UniApp
.
BackgroundAudioManager
[
'
onError
'
]
}
let
backgroundAudioManager
:
BackgroundAudioManager
export
const
getBackgroundAudioManager
=
defineSyncApi
<
API_TYPE_BACKGROUND_AUDIO
>
(
API_BACKGROUND_AUDIO
,
()
=>
backgroundAudioManager
||
(
backgroundAudioManager
=
new
BackgroundAudioManager
())
)
packages/uni-app-plus/src/service/api/index.ts
浏览文件 @
2c800299
...
...
@@ -17,8 +17,10 @@ export * from './keyboard/keyboard'
export
*
from
'
./network/downloadFile
'
export
*
from
'
./network/request
'
export
*
from
'
./network/socket
'
export
*
from
'
./context/createInnerAudioContext
'
export
*
from
'
./context/backgroundAudio
'
export
*
from
'
./location/getLocation
'
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录