mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
fix: audio from video files not being exported
This commit is contained in:
@@ -71,27 +71,54 @@ export async function collectAudioElements({
|
|||||||
if (canTracktHaveAudio(track) && track.muted) continue;
|
if (canTracktHaveAudio(track) && track.muted) continue;
|
||||||
|
|
||||||
for (const element of track.elements) {
|
for (const element of track.elements) {
|
||||||
if (element.type !== "audio") continue;
|
if (!canElementHaveAudio(element)) continue;
|
||||||
if (element.duration <= 0) continue;
|
if (element.duration <= 0) continue;
|
||||||
|
|
||||||
const isTrackMuted = canTracktHaveAudio(track) && track.muted;
|
const isTrackMuted = canTracktHaveAudio(track) && track.muted;
|
||||||
pendingElements.push(
|
|
||||||
resolveAudioBufferForElement({
|
if (element.type === "audio") {
|
||||||
element,
|
pendingElements.push(
|
||||||
mediaMap,
|
resolveAudioBufferForElement({
|
||||||
audioContext,
|
element,
|
||||||
}).then((audioBuffer) => {
|
mediaMap,
|
||||||
if (!audioBuffer) return null;
|
audioContext,
|
||||||
return {
|
}).then((audioBuffer) => {
|
||||||
buffer: audioBuffer,
|
if (!audioBuffer) return null;
|
||||||
startTime: element.startTime,
|
return {
|
||||||
duration: element.duration,
|
buffer: audioBuffer,
|
||||||
trimStart: element.trimStart,
|
startTime: element.startTime,
|
||||||
trimEnd: element.trimEnd,
|
duration: element.duration,
|
||||||
muted: element.muted || isTrackMuted,
|
trimStart: element.trimStart,
|
||||||
};
|
trimEnd: element.trimEnd,
|
||||||
}),
|
muted: element.muted || isTrackMuted,
|
||||||
);
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.type === "video") {
|
||||||
|
const mediaAsset = mediaMap.get(element.mediaId);
|
||||||
|
if (!mediaAsset || !mediaSupportsAudio({ media: mediaAsset })) continue;
|
||||||
|
|
||||||
|
pendingElements.push(
|
||||||
|
resolveAudioBufferForVideoElement({
|
||||||
|
mediaAsset,
|
||||||
|
audioContext,
|
||||||
|
}).then((audioBuffer) => {
|
||||||
|
if (!audioBuffer) return null;
|
||||||
|
const elementMuted = element.muted ?? false;
|
||||||
|
return {
|
||||||
|
buffer: audioBuffer,
|
||||||
|
startTime: element.startTime,
|
||||||
|
duration: element.duration,
|
||||||
|
trimStart: element.trimStart,
|
||||||
|
trimEnd: element.trimEnd,
|
||||||
|
muted: elementMuted || isTrackMuted,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,6 +163,22 @@ async function resolveAudioBufferForElement({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function resolveAudioBufferForVideoElement({
|
||||||
|
mediaAsset,
|
||||||
|
audioContext,
|
||||||
|
}: {
|
||||||
|
mediaAsset: MediaAsset;
|
||||||
|
audioContext: AudioContext;
|
||||||
|
}): Promise<AudioBuffer | null> {
|
||||||
|
try {
|
||||||
|
const arrayBuffer = await mediaAsset.file.arrayBuffer();
|
||||||
|
return await audioContext.decodeAudioData(arrayBuffer.slice(0));
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("Failed to decode video audio:", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface AudioMixSource {
|
interface AudioMixSource {
|
||||||
file: File;
|
file: File;
|
||||||
startTime: number;
|
startTime: number;
|
||||||
|
|||||||
Reference in New Issue
Block a user