mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-24 23:05:49 +00:00
Merge pull request #262 from webadderall/fix/export-pipeline-streaming-chunked
fix: streaming decode + chunked offline audio rendering for export
This commit is contained in:
+1
-1
@@ -2,4 +2,4 @@ reviews:
|
||||
auto_review:
|
||||
enabled: true
|
||||
base_branches:
|
||||
- "*"
|
||||
- ".*"
|
||||
|
||||
@@ -158,7 +158,10 @@ export async function muxNativeMacRecordingWithAudio(
|
||||
}
|
||||
|
||||
if (availableAudioInputs.length === 0) {
|
||||
console.warn("[mux] No valid audio files to mux");
|
||||
console.warn(
|
||||
"[mux] No valid audio files to mux — video will have no audio. " +
|
||||
`system=${systemAudioPath ?? "none"} mic=${microphonePath ?? "none"}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -4177,8 +4177,8 @@ export default function VideoEditor() {
|
||||
? Math.min(
|
||||
typeof exportProgress?.renderProgress === "number"
|
||||
? exportProgress.renderProgress
|
||||
: (exportProgress?.percentage ?? 99),
|
||||
99,
|
||||
: (exportProgress?.percentage ?? 100),
|
||||
100,
|
||||
)
|
||||
: null;
|
||||
const isLightningExportInProgress =
|
||||
@@ -4234,7 +4234,7 @@ export default function VideoEditor() {
|
||||
})
|
||||
: isExportFinalizing
|
||||
? t("editor.exportStatus.finalizingPercent", "Finalizing {{percent}}%", {
|
||||
percent: Math.round(exportFinalizingProgress ?? 99),
|
||||
percent: Math.round(exportFinalizingProgress ?? 100),
|
||||
})
|
||||
: t("editor.exportStatus.completePercent", "{{percent}}% complete", {
|
||||
percent: Math.round(exportProgress.percentage),
|
||||
@@ -4454,8 +4454,7 @@ export default function VideoEditor() {
|
||||
</p>
|
||||
{isRenderingAudio ? (
|
||||
<p className="mt-1 text-[11px] text-muted-foreground/70">
|
||||
Audio requires real-time playback for speed/overlay
|
||||
edits
|
||||
{t("editor.export.processingAudioEdits", "Processing audio with speed/overlay edits")}
|
||||
</p>
|
||||
) : exportRenderSpeedLabel ? (
|
||||
<p className="mt-1 text-[11px] text-muted-foreground/70">
|
||||
|
||||
@@ -122,6 +122,9 @@
|
||||
"complete": "Export complete",
|
||||
"savedSuccessfully": "Your file was saved successfully."
|
||||
},
|
||||
"export": {
|
||||
"processingAudioEdits": "Processing audio with speed/overlay edits"
|
||||
},
|
||||
"toolbar": {
|
||||
"addLayer": "Add Layer",
|
||||
"splitClip": "Split Clip (C)"
|
||||
|
||||
@@ -122,6 +122,9 @@
|
||||
"complete": "Exportación completada",
|
||||
"savedSuccessfully": "Tu archivo se guardó correctamente."
|
||||
},
|
||||
"export": {
|
||||
"processingAudioEdits": "Procesando audio con ediciones de velocidad/superposición"
|
||||
},
|
||||
"toolbar": {
|
||||
"addLayer": "Agregar capa",
|
||||
"splitClip": "Dividir clip (C)"
|
||||
|
||||
@@ -123,6 +123,9 @@
|
||||
"complete": "내보내기 완료",
|
||||
"savedSuccessfully": "파일이 성공적으로 저장되었습니다."
|
||||
},
|
||||
"export": {
|
||||
"processingAudioEdits": "속도/오버레이 편집으로 오디오 처리 중"
|
||||
},
|
||||
"toolbar": {
|
||||
"addLayer": "레이어 추가",
|
||||
"splitClip": "클립 분할 (C)"
|
||||
|
||||
@@ -123,6 +123,9 @@
|
||||
"complete": "Export voltooid",
|
||||
"savedSuccessfully": "Je bestand is succesvol opgeslagen."
|
||||
},
|
||||
"export": {
|
||||
"processingAudioEdits": "Audio verwerken met snelheids-/overlay-bewerkingen"
|
||||
},
|
||||
"toolbar": {
|
||||
"addLayer": "Laag toevoegen",
|
||||
"splitClip": "Clip splitsen (C)"
|
||||
|
||||
@@ -122,6 +122,9 @@
|
||||
"complete": "导出完成",
|
||||
"savedSuccessfully": "文件已成功保存。"
|
||||
},
|
||||
"export": {
|
||||
"processingAudioEdits": "正在处理带有速度/叠加编辑的音频"
|
||||
},
|
||||
"toolbar": {
|
||||
"addLayer": "添加图层",
|
||||
"splitClip": "拆分片段 (C)"
|
||||
|
||||
+916
-510
File diff suppressed because it is too large
Load Diff
@@ -434,6 +434,11 @@ export class ModernVideoExporter {
|
||||
"muxing queued video chunks",
|
||||
);
|
||||
|
||||
// Surface muxing errors before proceeding with finalization
|
||||
if (this.encoderError) {
|
||||
throw this.encoderError;
|
||||
}
|
||||
|
||||
if (nativeAudioPlan.audioMode !== "none" && !shouldUseFfmpegAudioFallback && !this.cancelled) {
|
||||
const demuxer = this.streamingDecoder.getDemuxer();
|
||||
if (
|
||||
@@ -1152,10 +1157,10 @@ export class ModernVideoExporter {
|
||||
const estimatedTimeRemaining =
|
||||
averageRenderFps > 0 ? remainingFrames / averageRenderFps : 0;
|
||||
const safeRenderProgress =
|
||||
phase === "finalizing" ? Math.max(0, Math.min(renderProgress ?? 99, 99)) : undefined;
|
||||
phase === "finalizing" ? Math.max(0, Math.min(renderProgress ?? 100, 100)) : undefined;
|
||||
const percentage =
|
||||
phase === "finalizing"
|
||||
? (safeRenderProgress ?? 99)
|
||||
? (safeRenderProgress ?? 100)
|
||||
: totalFrames > 0
|
||||
? (currentFrame / totalFrames) * 100
|
||||
: 100;
|
||||
@@ -1399,6 +1404,11 @@ export class ModernVideoExporter {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Muxing error:", error);
|
||||
const muxingError = error instanceof Error ? error : new Error(String(error));
|
||||
if (!this.encoderError) {
|
||||
this.encoderError = muxingError;
|
||||
}
|
||||
this.cancelled = true;
|
||||
}
|
||||
});
|
||||
this.encodeQueue--;
|
||||
|
||||
@@ -293,6 +293,11 @@ export class VideoExporter {
|
||||
"muxing queued video chunks",
|
||||
);
|
||||
|
||||
// Surface muxing errors before proceeding with finalization
|
||||
if (this.encoderError) {
|
||||
throw this.encoderError;
|
||||
}
|
||||
|
||||
if (hasAudio && !shouldUseFfmpegAudioFallback && !this.cancelled) {
|
||||
const demuxer = this.streamingDecoder.getDemuxer();
|
||||
if (demuxer || hasAudioRegions || hasSourceAudioFallback) {
|
||||
@@ -885,10 +890,10 @@ export class VideoExporter {
|
||||
const estimatedTimeRemaining =
|
||||
averageRenderFps > 0 ? remainingFrames / averageRenderFps : 0;
|
||||
const safeRenderProgress =
|
||||
phase === "finalizing" ? Math.max(0, Math.min(renderProgress ?? 99, 99)) : undefined;
|
||||
phase === "finalizing" ? Math.max(0, Math.min(renderProgress ?? 100, 100)) : undefined;
|
||||
const percentage =
|
||||
phase === "finalizing"
|
||||
? (safeRenderProgress ?? 99)
|
||||
? (safeRenderProgress ?? 100)
|
||||
: totalFrames > 0
|
||||
? (currentFrame / totalFrames) * 100
|
||||
: 100;
|
||||
@@ -979,6 +984,11 @@ export class VideoExporter {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Muxing error:", error);
|
||||
const muxingError = error instanceof Error ? error : new Error(String(error));
|
||||
if (!this.encoderError) {
|
||||
this.encoderError = muxingError;
|
||||
}
|
||||
this.cancelled = true;
|
||||
}
|
||||
});
|
||||
this.encodeQueue--;
|
||||
|
||||
Reference in New Issue
Block a user