mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-17 18:11:20 -08:00
refactor(audio): [PKG-AUDIO-03] separate track ownership and native lifecycle
This commit is contained in:
1 parent
803e87252e
commit
9c07ea830c
20 files changed
+12654
-250
No files matched your search
@@ -4,86 +4,162 @@
|
||||
* (c) 2017-2026 Harvey Zhao
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
function artplayerPluginAudioTrack(option) {
|
||||
return (art) => {
|
||||
let { url, offset = 0, sync = 0.3 } = option;
|
||||
const audio = new Audio();
|
||||
function createAudioTrack(option) {
|
||||
let { url, offset = 0, sync = 0.3 } = option;
|
||||
const audio = new Audio();
|
||||
let closed = false;
|
||||
function play() {
|
||||
if (closed || !url)
|
||||
return;
|
||||
audio.play().catch((error) => {
|
||||
if (!closed)
|
||||
console.warn(error);
|
||||
});
|
||||
}
|
||||
function pause() {
|
||||
if (!closed)
|
||||
audio.pause();
|
||||
}
|
||||
function destroy() {
|
||||
if (closed)
|
||||
return;
|
||||
closed = true;
|
||||
const failures = [];
|
||||
for (const release of [() => audio.pause(), () => audio.removeAttribute("src"), () => audio.load()]) {
|
||||
try {
|
||||
release();
|
||||
} catch (error) {
|
||||
failures.push(error);
|
||||
}
|
||||
}
|
||||
if (failures.length)
|
||||
throw failures[0];
|
||||
}
|
||||
try {
|
||||
audio.preload = "auto";
|
||||
if (url) {
|
||||
if (url)
|
||||
audio.src = url;
|
||||
} catch (error) {
|
||||
try {
|
||||
destroy();
|
||||
} catch {
|
||||
}
|
||||
function syncAudio() {
|
||||
if (!art.video || !url)
|
||||
throw error;
|
||||
}
|
||||
return {
|
||||
audio,
|
||||
play,
|
||||
pause,
|
||||
destroy,
|
||||
sync(time) {
|
||||
if (closed || !url)
|
||||
return;
|
||||
const videoTime = art.currentTime;
|
||||
const targetTime = videoTime + offset;
|
||||
if (Math.abs(audio.currentTime - targetTime) > sync) {
|
||||
audio.currentTime = targetTime;
|
||||
}
|
||||
}
|
||||
art.on("play", () => {
|
||||
if (!url)
|
||||
const target = time + offset;
|
||||
if (Math.abs(audio.currentTime - target) > sync)
|
||||
audio.currentTime = target;
|
||||
},
|
||||
update(newOption, playing) {
|
||||
if (closed)
|
||||
return;
|
||||
syncAudio();
|
||||
audio.play().catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
});
|
||||
art.on("pause", () => {
|
||||
audio.pause();
|
||||
});
|
||||
art.on("seek", () => {
|
||||
syncAudio();
|
||||
});
|
||||
art.on("video:timeupdate", () => {
|
||||
if (art.playing) {
|
||||
syncAudio();
|
||||
}
|
||||
});
|
||||
art.on("video:ratechange", () => {
|
||||
audio.playbackRate = art.video.playbackRate;
|
||||
});
|
||||
art.on("video:volumechange", () => {
|
||||
audio.volume = art.volume;
|
||||
audio.muted = art.muted;
|
||||
});
|
||||
art.on("video:waiting", () => {
|
||||
audio.pause();
|
||||
});
|
||||
art.on("video:playing", () => {
|
||||
if (url && art.playing) {
|
||||
audio.play().catch((err) => {
|
||||
console.warn(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
art.on("destroy", () => {
|
||||
audio.pause();
|
||||
audio.src = "";
|
||||
audio.load();
|
||||
});
|
||||
function update(newOption) {
|
||||
if (newOption.url && newOption.url !== url) {
|
||||
url = newOption.url;
|
||||
audio.src = url;
|
||||
if (art.playing) {
|
||||
audio.play().catch((err) => console.warn(err));
|
||||
if (playing)
|
||||
play();
|
||||
}
|
||||
if (newOption.offset !== void 0)
|
||||
offset = newOption.offset;
|
||||
if (newOption.sync !== void 0)
|
||||
sync = newOption.sync;
|
||||
}
|
||||
};
|
||||
}
|
||||
function artplayerPluginAudioTrack(option) {
|
||||
return (art) => {
|
||||
const track = createAudioTrack(option);
|
||||
const { audio } = track;
|
||||
const subscriptions = [];
|
||||
let active = true;
|
||||
function syncAudio() {
|
||||
if (art.video)
|
||||
track.sync(art.currentTime);
|
||||
}
|
||||
function listen(event, callback) {
|
||||
const listener = () => {
|
||||
if (active)
|
||||
callback();
|
||||
};
|
||||
subscriptions.push([event, listener]);
|
||||
art.on(event, listener);
|
||||
}
|
||||
function destroy() {
|
||||
if (!active)
|
||||
return;
|
||||
active = false;
|
||||
const failures = [];
|
||||
for (const [event, listener] of subscriptions.splice(0)) {
|
||||
try {
|
||||
art.off(event, listener);
|
||||
} catch (error) {
|
||||
failures.push(error);
|
||||
}
|
||||
}
|
||||
if (newOption.offset !== void 0) {
|
||||
offset = newOption.offset;
|
||||
}
|
||||
if (newOption.sync !== void 0) {
|
||||
sync = newOption.sync;
|
||||
try {
|
||||
track.destroy();
|
||||
} catch (error) {
|
||||
failures.push(error);
|
||||
}
|
||||
if (failures.length)
|
||||
throw failures[0];
|
||||
}
|
||||
try {
|
||||
listen("play", () => {
|
||||
syncAudio();
|
||||
track.play();
|
||||
});
|
||||
for (const event of ["pause", "video:pause", "video:ended", "video:waiting", "video:emptied", "video:seeking"])
|
||||
listen(event, track.pause);
|
||||
listen("seek", syncAudio);
|
||||
listen("video:seeked", () => {
|
||||
syncAudio();
|
||||
if (art.playing)
|
||||
track.play();
|
||||
});
|
||||
listen("video:timeupdate", () => {
|
||||
if (art.playing)
|
||||
syncAudio();
|
||||
});
|
||||
listen("video:ratechange", () => {
|
||||
audio.playbackRate = art.video.playbackRate;
|
||||
});
|
||||
listen("video:volumechange", () => {
|
||||
audio.volume = art.volume;
|
||||
audio.muted = art.muted;
|
||||
});
|
||||
listen("video:playing", () => {
|
||||
if (art.playing) {
|
||||
syncAudio();
|
||||
track.play();
|
||||
}
|
||||
});
|
||||
listen("destroy", destroy);
|
||||
audio.volume = art.volume;
|
||||
audio.muted = art.muted;
|
||||
audio.playbackRate = art.video?.playbackRate || 1;
|
||||
} catch (error) {
|
||||
try {
|
||||
destroy();
|
||||
} catch {
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
audio.volume = art.volume;
|
||||
audio.muted = art.muted;
|
||||
audio.playbackRate = art.video?.playbackRate || 1;
|
||||
return {
|
||||
name: "artplayerPluginAudioTrack",
|
||||
audio,
|
||||
update
|
||||
update(newOption) {
|
||||
if (active)
|
||||
track.update(newOption, art.playing);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user