fix: audio play bug for ios safari. (#285)

* fix: audio play bug for ios safari. (WIP).

* chore: Repair and can pop up the playback prompt dialog box correctly.

* chore: add AudioContext to reduce playback delay.
This commit is contained in:
CloudWebRTC
2023-05-16 10:28:09 +08:00
committed by GitHub
parent 2b1e7f2e5f
commit 0b8aeeeba1
10 changed files with 146 additions and 6 deletions
+11 -4
View File
@@ -1,4 +1,5 @@
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import 'package:livekit_client/src/internal/events.dart';
import '../../proto/livekit_models.pb.dart' as lk_models;
import '../../types/other.dart';
@@ -28,10 +29,16 @@ class RemoteAudioTrack extends RemoteTrack
Future<bool> start() async {
final didStart = await super.start();
if (didStart) {
// web support
audio.startAudio(getCid(), mediaStreamTrack);
if (_deviceId != null) {
audio.setSinkId(getCid(), _deviceId!);
try {
// web support
await audio.startAudio(getCid(), mediaStreamTrack);
if (_deviceId != null) {
audio.setSinkId(getCid(), _deviceId!);
}
} catch (e) {
if (e.toString().startsWith('NotAllowedError')) {
events.emit(AudioPlaybackFailed(track: this));
}
}
}
return didStart;
+5 -1
View File
@@ -1,6 +1,6 @@
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
void startAudio(String id, rtc.MediaStreamTrack stream) {
Future<dynamic> startAudio(String id, rtc.MediaStreamTrack stream) async {
// do nothing
}
@@ -8,6 +8,10 @@ void stopAudio(String id) {
// do nothing
}
Future<bool> startAllAudioElement() async {
return true;
}
void setSinkId(String id, String deviceId) {
// do nothing
}
+18 -1
View File
@@ -1,6 +1,7 @@
import 'dart:html' as html;
import 'dart:js_util' as jsutil;
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import 'package:js_bindings/js_bindings.dart' as js_bindings;
// ignore: implementation_imports
import 'package:dart_webrtc/src/media_stream_track_impl.dart'; // import_sorter: keep
@@ -8,10 +9,14 @@ import 'package:dart_webrtc/src/media_stream_track_impl.dart'; // import_sorter:
const audioContainerId = 'livekit_audio_container';
const audioPrefix = 'livekit_audio_';
void startAudio(String id, rtc.MediaStreamTrack track) {
js_bindings.AudioContext _audioContext = js_bindings.AudioContext();
Map<String, html.Element> _audioElements = {};
Future<dynamic> startAudio(String id, rtc.MediaStreamTrack track) async {
if (track is! MediaStreamTrackWeb) {
return;
}
final elementId = audioPrefix + id;
var audioElement = html.document.getElementById(elementId);
if (audioElement == null) {
@@ -19,6 +24,7 @@ void startAudio(String id, rtc.MediaStreamTrack track) {
..id = elementId
..autoplay = true;
findOrCreateAudioContainer().append(audioElement);
_audioElements[id] = audioElement;
}
if (audioElement is! html.AudioElement) {
@@ -27,6 +33,16 @@ void startAudio(String id, rtc.MediaStreamTrack track) {
final audioStream = html.MediaStream();
audioStream.addTrack(track.jsTrack);
audioElement.srcObject = audioStream;
return audioElement.play();
}
Future<bool> startAllAudioElement() async {
for (final element in _audioElements.values) {
if (element is html.AudioElement) {
await element.play();
}
}
return _audioContext.state == js_bindings.AudioContextState.running;
}
void stopAudio(String id) {
@@ -35,6 +51,7 @@ void stopAudio(String id) {
if (audioElement is html.AudioElement) {
audioElement.srcObject = null;
}
_audioElements.remove(id);
audioElement.remove();
}
}