bugfixes
This commit is contained in:
parent
fbac1c6327
commit
19faed7a40
@ -368,7 +368,7 @@ func appendFileAndRemove(dstPath, srcPath string) error {
|
||||
return err
|
||||
}
|
||||
if sfi == nil || sfi.IsDir() || sfi.Size() <= 0 {
|
||||
_ = os.Remove(srcPath)
|
||||
_ = removeWithRetry(srcPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -376,19 +376,55 @@ func appendFileAndRemove(dstPath, srcPath string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
dst, err := os.OpenFile(dstPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
if _, err := io.Copy(dst, src); err != nil {
|
||||
_ = src.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Remove(srcPath)
|
||||
_, copyErr := io.Copy(dst, src)
|
||||
|
||||
closeSrcErr := src.Close()
|
||||
closeDstErr := dst.Close()
|
||||
|
||||
if copyErr != nil {
|
||||
return copyErr
|
||||
}
|
||||
if closeSrcErr != nil {
|
||||
return closeSrcErr
|
||||
}
|
||||
if closeDstErr != nil {
|
||||
return closeDstErr
|
||||
}
|
||||
|
||||
if err := removeWithRetry(srcPath); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanupHLSRetryChunks(outFile string) {
|
||||
dir := filepath.Dir(outFile)
|
||||
ext := filepath.Ext(outFile)
|
||||
base := strings.TrimSuffix(filepath.Base(outFile), ext)
|
||||
|
||||
canonical := canonicalAssetIDFromName(base)
|
||||
if canonical == "" {
|
||||
canonical = base
|
||||
}
|
||||
|
||||
pattern := filepath.Join(dir, fmt.Sprintf(".%s.retry.*%s", canonical, ext))
|
||||
|
||||
matches, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range matches {
|
||||
_ = removeWithRetry(p)
|
||||
}
|
||||
}
|
||||
|
||||
func handleM3U8Mode(
|
||||
@ -419,10 +455,26 @@ func handleM3U8Mode(
|
||||
}
|
||||
}
|
||||
|
||||
if strings.TrimSpace(outFile) == "" {
|
||||
outFile = strings.TrimSpace(outFile)
|
||||
if outFile == "" {
|
||||
return errors.New("output file path leer")
|
||||
}
|
||||
|
||||
cleanupHLSRetryChunks(outFile)
|
||||
defer cleanupHLSRetryChunks(outFile)
|
||||
|
||||
ext := strings.ToLower(filepath.Ext(outFile))
|
||||
if ext != ".ts" && ext != ".mp4" {
|
||||
return fmt.Errorf("nicht unterstützte output-endung: %q", ext)
|
||||
}
|
||||
|
||||
// Wichtig: ffmpeg schreibt in temporäre Retry-Datei.
|
||||
// Danach wird sie an outFile angehängt und gelöscht.
|
||||
retryOut := hlsRetryChunkPath(outFile, 1)
|
||||
defer func() {
|
||||
_ = removeWithRetry(retryOut)
|
||||
}()
|
||||
|
||||
args := []string{
|
||||
"-y",
|
||||
"-hide_banner",
|
||||
@ -452,8 +504,6 @@ func handleM3U8Mode(
|
||||
return args
|
||||
}
|
||||
|
||||
ext := strings.ToLower(filepath.Ext(strings.TrimSpace(outFile)))
|
||||
|
||||
if audioURL != "" {
|
||||
args = appendInputOptions(args)
|
||||
args = append(args, "-i", videoURL)
|
||||
@ -484,21 +534,19 @@ func handleM3U8Mode(
|
||||
case ".ts":
|
||||
args = append(args,
|
||||
"-f", "mpegts",
|
||||
outFile,
|
||||
retryOut,
|
||||
)
|
||||
case ".mp4":
|
||||
args = append(args,
|
||||
"-movflags", "+faststart",
|
||||
outFile,
|
||||
retryOut,
|
||||
)
|
||||
default:
|
||||
return fmt.Errorf("nicht unterstützte output-endung: %q", ext)
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, ffmpegPath, args...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
HideWindow: true,
|
||||
CreationFlags: 0x08000000, // CREATE_NO_WINDOW
|
||||
CreationFlags: 0x08000000,
|
||||
}
|
||||
|
||||
var stderr bytes.Buffer
|
||||
@ -520,16 +568,15 @@ func handleM3U8Mode(
|
||||
case <-stopStat:
|
||||
return
|
||||
case <-t.C:
|
||||
fi, err := os.Stat(outFile)
|
||||
if err != nil || fi == nil || fi.IsDir() {
|
||||
continue
|
||||
}
|
||||
mainSize := safeFileSize(outFile)
|
||||
retrySize := safeFileSize(retryOut)
|
||||
sz := mainSize + retrySize
|
||||
|
||||
sz := fi.Size()
|
||||
if sz > 0 && sz != last {
|
||||
jobsMu.Lock()
|
||||
job.SizeBytes = sz
|
||||
jobsMu.Unlock()
|
||||
|
||||
last = sz
|
||||
_ = publishJob(job.ID)
|
||||
}
|
||||
@ -549,6 +596,10 @@ func handleM3U8Mode(
|
||||
return fmt.Errorf("ffmpeg m3u8 failed: %w", err)
|
||||
}
|
||||
|
||||
if err := appendFileAndRemove(outFile, retryOut); err != nil {
|
||||
return fmt.Errorf("retry chunk übernehmen fehlgeschlagen: %w", err)
|
||||
}
|
||||
|
||||
if job != nil {
|
||||
if fi, statErr := os.Stat(outFile); statErr == nil && fi != nil && !fi.IsDir() {
|
||||
jobsMu.Lock()
|
||||
|
||||
@ -2043,9 +2043,9 @@ export default function TrainingTab(props: {
|
||||
|
||||
progressTimer = window.setInterval(() => {
|
||||
setAnalysisProgress((value) => {
|
||||
if (value < 35) return value + 4
|
||||
if (value < 65) return value + 2
|
||||
if (value < 88) return value + 1
|
||||
if (value < 35) return Math.min(35, value + 4)
|
||||
if (value < 65) return Math.min(65, value + 2)
|
||||
if (value < 95) return Math.min(95, value + 1)
|
||||
return value
|
||||
})
|
||||
}, 350)
|
||||
@ -2117,7 +2117,7 @@ export default function TrainingTab(props: {
|
||||
setLoading(false)
|
||||
setAnalysisProgress(0)
|
||||
setAnalysisStep('')
|
||||
}, 150)
|
||||
}, 500)
|
||||
}
|
||||
}, [])
|
||||
|
||||
@ -2159,6 +2159,8 @@ export default function TrainingTab(props: {
|
||||
setTraining(Boolean(job?.running))
|
||||
|
||||
if (job?.message && !job.running) {
|
||||
setTrainingProgress(100)
|
||||
setTrainingStep('Training abgeschlossen.')
|
||||
setMessage((prev) => prev || String(job.message))
|
||||
}
|
||||
|
||||
@ -2311,9 +2313,12 @@ export default function TrainingTab(props: {
|
||||
|
||||
useEffect(() => {
|
||||
if (!trainingRunning) {
|
||||
const timer = window.setTimeout(() => {
|
||||
setTrainingProgress(0)
|
||||
setTrainingStep('')
|
||||
return
|
||||
}, 800)
|
||||
|
||||
return () => window.clearTimeout(timer)
|
||||
}
|
||||
|
||||
const serverProgress = Number(trainingStatus?.training?.progress ?? 0)
|
||||
@ -3208,8 +3213,18 @@ export default function TrainingTab(props: {
|
||||
disabled={uiLocked}
|
||||
className={[
|
||||
isActiveBox
|
||||
? 'pointer-events-auto absolute z-20 flex h-7 w-7 touch-none items-center justify-center rounded-full bg-transparent p-0 opacity-100 disabled:opacity-50 sm:h-5 sm:w-5'
|
||||
: 'pointer-events-none absolute z-20 hidden h-7 w-7 touch-none items-center justify-center rounded-full bg-transparent p-0 opacity-100 disabled:opacity-50 sm:h-5 sm:w-5',
|
||||
? [
|
||||
'pointer-events-auto absolute z-20 flex h-7 w-7 touch-none items-center justify-center',
|
||||
'appearance-none rounded-none border-0 p-0 opacity-100 shadow-none ring-0',
|
||||
'!bg-transparent hover:!bg-transparent active:!bg-transparent focus:!bg-transparent',
|
||||
'focus:outline-none disabled:opacity-50 sm:h-5 sm:w-5',
|
||||
].join(' ')
|
||||
: [
|
||||
'pointer-events-none absolute z-20 hidden h-7 w-7 touch-none items-center justify-center',
|
||||
'appearance-none rounded-none border-0 p-0 opacity-100 shadow-none ring-0',
|
||||
'!bg-transparent hover:!bg-transparent active:!bg-transparent focus:!bg-transparent',
|
||||
'focus:outline-none disabled:opacity-50 sm:h-5 sm:w-5',
|
||||
].join(' '),
|
||||
handle === 'nw' ? '-left-3.5 -top-3.5 cursor-nwse-resize sm:-left-2.5 sm:-top-2.5' : '',
|
||||
handle === 'ne' ? '-right-3.5 -top-3.5 cursor-nesw-resize sm:-right-2.5 sm:-top-2.5' : '',
|
||||
handle === 'sw' ? '-bottom-3.5 -left-3.5 cursor-nesw-resize sm:-bottom-2.5 sm:-left-2.5' : '',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user