问题描述
那里!
我正在开发一个页面,它同时使用了 responsevoice.js 和一个脚本来控制 vimeo(通过 iframe)并执行一些操作。
几乎一切正常:我有一个播放按钮,一旦触发就会读取带有响应语音的文本。
问题是如果我不小心同时播放两个,音频会混淆。
我想在播放 vimeo 时停止响应语音,反之亦然。我在 javascript 中尝试了一些东西,但它不起作用。我认为一切都很好,但由于我是初学者,可能我做错了什么。
有人可以帮我吗?非常感谢您的关注!
struct ContentView: View {
@StateObject var player: AudioPlayerAV = AudioPlayerAV()
@State private var urlText = "https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_5MG.mp3"
var body: some View {
TextField("",text: $urlText)
Button(action: {
if let url = URL(string: urlText) {
player.loadplayer(avPlayer: AVPlayer(url: url))
player.play()
} else {
print("not valid")
}
}) {
Text("Load")
}
}
}
struct Response: Codable {
// ... some fields here
}
let timeScale = CMTimeScale(1000)
let time = CMTime(seconds: 0.5,preferredTimescale: timeScale)
enum PlayerScrubState {
case reset
case scrubStarted
case scrubEnded(TimeInterval)
}
final class AudioPlayerAV: NSObject,ObservableObject {
@Published var displayTime: TimeInterval = 0
@Published var observedTime: TimeInterval = 0
@Published var itemDuration: TimeInterval = 0
@Published var audioFinishedplaying: Bool = false
@Published var timeControlStatus: AVPlayer.TimeControlStatus = .paused
fileprivate var itemDurationKVOPublisher: AnyCancellable?
fileprivate var timeControlStatusKVOPublisher: AnyCancellable?
fileprivate var avPlayer: AVPlayer?
fileprivate var periodicTimeObserver: Any?
var scrubState: PlayerScrubState = .reset {
didSet {
switch scrubState {
case .reset:
return
case .scrubStarted:
return
case .scrubEnded(let seekTime):
avPlayer?.seek(to: CMTime(seconds: seekTime,preferredTimescale: 1000))
}
}
}
func loadplayer(avPlayer: AVPlayer) {
removeObservers()
self.avPlayer = avPlayer
addPeriodicTimeObserver()
addTimeControlStatusObserver()
addItemDurationPublisher()
NotificationCenter.default.addobserver(forName: NSNotification.Name.AVPlayerItemDidplayToEndTime,object: nil,queue: .main) { (_) in
self.audioFinishedplaying = true
}
}
func removeObservers() {
removePeriodicTimeObserver()
timeControlStatusKVOPublisher?.cancel()
itemDurationKVOPublisher?.cancel()
NotificationCenter.default.removeObserver(self)
}
deinit {
removeObservers()
}
func play() {
self.avPlayer?.play()
}
func pause() {
self.avPlayer?.pause()
}
fileprivate func addPeriodicTimeObserver() {
self.periodicTimeObserver = avPlayer?.addPeriodicTimeObserver(forInterval: time,queue: .main) { [weak self] (time) in
guard let self = self else { return }
self.observedTime = time.seconds
switch self.scrubState {
case .reset:
self.displayTime = time.seconds
case .scrubStarted:
break
case .scrubEnded(let seekTime):
self.scrubState = .reset
self.displayTime = seekTime
}
}
}
fileprivate func removePeriodicTimeObserver() {
guard let periodicTimeObserver = self.periodicTimeObserver else {
return
}
avPlayer?.removeTimeObserver(periodicTimeObserver)
self.periodicTimeObserver = nil
}
fileprivate func addTimeControlStatusObserver() {
guard let avPlayer = avPlayer else {
return
}
timeControlStatusKVOPublisher = avPlayer
.publisher(for: \.timeControlStatus)
.receive(on: dispatchQueue.main)
.sink(receiveValue: { [weak self] (newStatus) in
guard let self = self else { return }
self.timeControlStatus = newStatus
}
)
}
fileprivate func addItemDurationPublisher() {
guard let avPlayer = avPlayer else {
return
}
itemDurationKVOPublisher = avPlayer
.publisher(for: \.currentItem?.duration)
.receive(on: dispatchQueue.main)
.sink(receiveValue: { [weak self] (newStatus) in
guard let newStatus = newStatus,let self = self else { return }
self.itemDuration = newStatus.seconds
}
)
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)