Compare commits
No commits in common. "e3aebdcbb73e979de99232b85d9bd17f677d5176" and "7a82542f91bb033cc84294c582972a8f4b36e765" have entirely different histories.
e3aebdcbb7
...
7a82542f91
1
main.go
1
main.go
|
|
@ -997,7 +997,6 @@ type appState struct {
|
|||
subtitleBurnOutput string
|
||||
subtitleBurnEnabled bool
|
||||
subtitleCuesRefresh func()
|
||||
subtitleTimeOffset float64
|
||||
}
|
||||
|
||||
type mergeClip struct {
|
||||
|
|
|
|||
|
|
@ -9,21 +9,21 @@ alias VideoTools="bash $PROJECT_ROOT/scripts/run.sh"
|
|||
|
||||
# Also create a rebuild function for quick rebuilds
|
||||
VideoToolsRebuild() {
|
||||
echo "Rebuilding VideoTools..."
|
||||
echo "🔨 Rebuilding VideoTools..."
|
||||
bash "$PROJECT_ROOT/scripts/build.sh"
|
||||
}
|
||||
|
||||
# Create a clean function
|
||||
VideoToolsClean() {
|
||||
echo "Cleaning VideoTools build artifacts..."
|
||||
echo "🧹 Cleaning VideoTools build artifacts..."
|
||||
cd "$PROJECT_ROOT"
|
||||
go clean -cache -modcache -testcache
|
||||
rm -f "$PROJECT_ROOT/VideoTools"
|
||||
echo "Clean complete"
|
||||
echo "✓ Clean complete"
|
||||
}
|
||||
|
||||
echo "════════════════════════════════════════════════════════════════"
|
||||
echo "VideoTools Commands Available"
|
||||
echo "✅ VideoTools Commands Available"
|
||||
echo "════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
|
|
|
|||
|
|
@ -17,49 +17,49 @@ echo ""
|
|||
|
||||
# Check if go is installed
|
||||
if ! command -v go &> /dev/null; then
|
||||
echo "ERROR: Go is not installed. Please install Go 1.21 or later."
|
||||
echo "❌ ERROR: Go is not installed. Please install Go 1.21 or later."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Go version:"
|
||||
echo "📦 Go version:"
|
||||
go version
|
||||
echo ""
|
||||
|
||||
# Change to project directory
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "Cleaning previous builds and cache..."
|
||||
echo "🧹 Cleaning previous builds and cache..."
|
||||
go clean -cache -testcache 2>/dev/null || true
|
||||
rm -f "$BUILD_OUTPUT" 2>/dev/null || true
|
||||
# Also clear build cache directory to avoid permission issues
|
||||
rm -rf "${GOCACHE:-$HOME/.cache/go-build}" 2>/dev/null || true
|
||||
echo "Cache cleaned"
|
||||
echo "✓ Cache cleaned"
|
||||
echo ""
|
||||
|
||||
echo "Downloading and verifying dependencies (skips if already cached)..."
|
||||
echo "⬇️ Downloading and verifying dependencies (skips if already cached)..."
|
||||
if go list -m all >/dev/null 2>&1; then
|
||||
echo "Dependencies already present"
|
||||
echo "✓ Dependencies already present"
|
||||
else
|
||||
if go mod download && go mod verify; then
|
||||
echo "Dependencies downloaded and verified"
|
||||
echo "✓ Dependencies downloaded and verified"
|
||||
else
|
||||
echo "Failed to download/verify modules. Check network/GOPROXY or try again."
|
||||
echo "❌ Failed to download/verify modules. Check network/GOPROXY or try again."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "Building VideoTools..."
|
||||
echo "🔨 Building VideoTools..."
|
||||
# Fyne needs cgo for GLFW/OpenGL bindings; build with CGO enabled.
|
||||
export CGO_ENABLED=1
|
||||
export GOCACHE="$PROJECT_ROOT/.cache/go-build"
|
||||
export GOMODCACHE="$PROJECT_ROOT/.cache/go-mod"
|
||||
mkdir -p "$GOCACHE" "$GOMODCACHE"
|
||||
if go build -o "$BUILD_OUTPUT" .; then
|
||||
echo "Build successful! (VideoTools $APP_VERSION)"
|
||||
echo "✓ Build successful! (VideoTools $APP_VERSION)"
|
||||
echo ""
|
||||
echo "════════════════════════════════════════════════════════════════"
|
||||
echo "BUILD COMPLETE - $APP_VERSION"
|
||||
echo "✅ BUILD COMPLETE - $APP_VERSION"
|
||||
echo "════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
echo "Output: $BUILD_OUTPUT"
|
||||
|
|
@ -74,7 +74,7 @@ if go build -o "$BUILD_OUTPUT" .; then
|
|||
echo " VideoTools"
|
||||
echo ""
|
||||
else
|
||||
echo "Build failed! (VideoTools $APP_VERSION)"
|
||||
echo "❌ Build failed! (VideoTools $APP_VERSION)"
|
||||
echo "Diagnostics: version=$APP_VERSION os=$(uname -s) arch=$(uname -m) go=$(go version | awk '{print $3}')"
|
||||
echo ""
|
||||
echo "Help: check the Go error messages above."
|
||||
|
|
|
|||
|
|
@ -15,17 +15,17 @@ echo ""
|
|||
|
||||
# Check if go is installed
|
||||
if ! command -v go &> /dev/null; then
|
||||
echo "ERROR: Go is not installed. Please install Go 1.21 or later."
|
||||
echo "❌ ERROR: Go is not installed. Please install Go 1.21 or later."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Go version:"
|
||||
echo "📦 Go version:"
|
||||
go version
|
||||
echo ""
|
||||
|
||||
# Check if MinGW-w64 is installed
|
||||
if ! command -v x86_64-w64-mingw32-gcc &> /dev/null; then
|
||||
echo "ERROR: MinGW-w64 cross-compiler not found!"
|
||||
echo "❌ ERROR: MinGW-w64 cross-compiler not found!"
|
||||
echo ""
|
||||
echo "To install on Fedora/RHEL:"
|
||||
echo " sudo dnf install mingw64-gcc mingw64-winpthreads-static"
|
||||
|
|
@ -36,26 +36,26 @@ if ! command -v x86_64-w64-mingw32-gcc &> /dev/null; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
echo "MinGW-w64 detected:"
|
||||
echo "🔧 MinGW-w64 detected:"
|
||||
x86_64-w64-mingw32-gcc --version | head -1
|
||||
echo ""
|
||||
|
||||
# Change to project directory
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "Cleaning previous Windows builds..."
|
||||
echo "🧹 Cleaning previous Windows builds..."
|
||||
rm -f "$BUILD_OUTPUT" 2>/dev/null || true
|
||||
rm -rf "$DIST_DIR" 2>/dev/null || true
|
||||
echo "Previous builds cleaned"
|
||||
echo "✓ Previous builds cleaned"
|
||||
echo ""
|
||||
|
||||
echo "Downloading and verifying dependencies..."
|
||||
echo "⬇️ Downloading and verifying dependencies..."
|
||||
go mod download
|
||||
go mod verify
|
||||
echo "Dependencies verified"
|
||||
echo "✓ Dependencies verified"
|
||||
echo ""
|
||||
|
||||
echo "Cross-compiling for Windows (amd64)..."
|
||||
echo "🔨 Cross-compiling for Windows (amd64)..."
|
||||
echo " Target: windows/amd64"
|
||||
echo " Compiler: x86_64-w64-mingw32-gcc"
|
||||
echo ""
|
||||
|
|
@ -73,27 +73,27 @@ export CXX=x86_64-w64-mingw32-g++
|
|||
LDFLAGS="-H windowsgui -s -w"
|
||||
|
||||
if go build -ldflags="$LDFLAGS" -o "$BUILD_OUTPUT" .; then
|
||||
echo "Cross-compilation successful!"
|
||||
echo "✓ Cross-compilation successful!"
|
||||
echo ""
|
||||
else
|
||||
echo "Build failed!"
|
||||
echo "❌ Build failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Creating distribution package..."
|
||||
echo "📦 Creating distribution package..."
|
||||
mkdir -p "$DIST_DIR"
|
||||
|
||||
# Copy executable
|
||||
cp "$BUILD_OUTPUT" "$DIST_DIR/"
|
||||
echo "Copied VideoTools.exe"
|
||||
echo "✓ Copied VideoTools.exe"
|
||||
|
||||
# Copy documentation
|
||||
cp README.md "$DIST_DIR/" 2>/dev/null || echo "WARNING: README.md not found"
|
||||
cp LICENSE "$DIST_DIR/" 2>/dev/null || echo "WARNING: LICENSE not found"
|
||||
cp README.md "$DIST_DIR/" 2>/dev/null || echo "⚠️ README.md not found"
|
||||
cp LICENSE "$DIST_DIR/" 2>/dev/null || echo "⚠️ LICENSE not found"
|
||||
|
||||
# Download and bundle FFmpeg automatically
|
||||
if [ ! -f "ffmpeg.exe" ]; then
|
||||
echo "FFmpeg not found locally, downloading..."
|
||||
echo "📥 FFmpeg not found locally, downloading..."
|
||||
FFMPEG_URL="https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip"
|
||||
FFMPEG_ZIP="$PROJECT_ROOT/ffmpeg-windows.zip"
|
||||
|
||||
|
|
@ -102,14 +102,14 @@ if [ ! -f "ffmpeg.exe" ]; then
|
|||
elif command -v curl &> /dev/null; then
|
||||
curl -L "$FFMPEG_URL" -o "$FFMPEG_ZIP" --progress-bar
|
||||
else
|
||||
echo "WARNING: wget or curl not found. Cannot download FFmpeg automatically."
|
||||
echo "⚠️ wget or curl not found. Cannot download FFmpeg automatically."
|
||||
echo " Please download manually from: $FFMPEG_URL"
|
||||
echo " Extract ffmpeg.exe and ffprobe.exe to project root"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ -f "$FFMPEG_ZIP" ]; then
|
||||
echo "Extracting FFmpeg..."
|
||||
echo "📦 Extracting FFmpeg..."
|
||||
unzip -q "$FFMPEG_ZIP" "*/bin/ffmpeg.exe" "*/bin/ffprobe.exe" -d "$PROJECT_ROOT/ffmpeg-temp"
|
||||
|
||||
# Find and copy the executables (they're nested in a versioned directory)
|
||||
|
|
@ -118,28 +118,28 @@ if [ ! -f "ffmpeg.exe" ]; then
|
|||
|
||||
# Cleanup
|
||||
rm -rf "$PROJECT_ROOT/ffmpeg-temp" "$FFMPEG_ZIP"
|
||||
echo "FFmpeg downloaded and extracted"
|
||||
echo "✓ FFmpeg downloaded and extracted"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Bundle FFmpeg with the distribution
|
||||
if [ -f "ffmpeg.exe" ]; then
|
||||
cp ffmpeg.exe "$DIST_DIR/"
|
||||
echo "Bundled ffmpeg.exe"
|
||||
echo "✓ Bundled ffmpeg.exe"
|
||||
else
|
||||
echo "WARNING: ffmpeg.exe not found - distribution will require separate FFmpeg installation"
|
||||
echo "⚠️ ffmpeg.exe not found - distribution will require separate FFmpeg installation"
|
||||
fi
|
||||
|
||||
if [ -f "ffprobe.exe" ]; then
|
||||
cp ffprobe.exe "$DIST_DIR/"
|
||||
echo "Bundled ffprobe.exe"
|
||||
echo "✓ Bundled ffprobe.exe"
|
||||
else
|
||||
echo "WARNING: ffprobe.exe not found"
|
||||
echo "⚠️ ffprobe.exe not found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "════════════════════════════════════════════════════════════════"
|
||||
echo "WINDOWS BUILD COMPLETE"
|
||||
echo "✅ WINDOWS BUILD COMPLETE"
|
||||
echo "════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
echo "Output directory: $DIST_DIR"
|
||||
|
|
|
|||
|
|
@ -15,23 +15,23 @@ case "$PLATFORM" in
|
|||
Linux*) OS="Linux" ;;
|
||||
Darwin*) OS="macOS" ;;
|
||||
CYGWIN*|MINGW*|MSYS*) OS="Windows" ;;
|
||||
*) echo "Unknown platform: $PLATFORM"; exit 1 ;;
|
||||
*) echo "❌ Unknown platform: $PLATFORM"; exit 1 ;;
|
||||
esac
|
||||
|
||||
echo "════════════════════════════════════════════════════════════════"
|
||||
echo " VideoTools ${OS} Build"
|
||||
echo "════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
echo "Detected platform: $OS"
|
||||
echo "🔍 Detected platform: $OS"
|
||||
echo ""
|
||||
|
||||
# Go check
|
||||
if ! command -v go >/dev/null 2>&1; then
|
||||
echo "ERROR: Go is not installed. Please install Go 1.21+ (go version currently missing)."
|
||||
echo "❌ ERROR: Go is not installed. Please install Go 1.21+ (go version currently missing)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Go version:"
|
||||
echo "📦 Go version:"
|
||||
go version
|
||||
echo ""
|
||||
|
||||
|
|
@ -50,26 +50,26 @@ case "$OS" in
|
|||
echo ""
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "Cleaning previous builds..."
|
||||
echo "🧹 Cleaning previous builds..."
|
||||
rm -f VideoTools.exe 2>/dev/null || true
|
||||
# Clear Go cache to avoid permission issues
|
||||
go clean -cache -modcache -testcache 2>/dev/null || true
|
||||
echo "Cache cleaned"
|
||||
echo "✓ Cache cleaned"
|
||||
echo ""
|
||||
|
||||
echo "Downloading dependencies..."
|
||||
echo "⬇️ Downloading dependencies..."
|
||||
go mod download
|
||||
echo "Dependencies downloaded"
|
||||
echo "✓ Dependencies downloaded"
|
||||
echo ""
|
||||
|
||||
echo "Building VideoTools $APP_VERSION for Windows..."
|
||||
echo "🔨 Building VideoTools $APP_VERSION for Windows..."
|
||||
export CGO_ENABLED=1
|
||||
if go build -ldflags="-H windowsgui -s -w" -o VideoTools.exe .; then
|
||||
echo "Build successful! (VideoTools $APP_VERSION)"
|
||||
echo "✓ Build successful! (VideoTools $APP_VERSION)"
|
||||
echo ""
|
||||
if [ -f "setup-windows.bat" ]; then
|
||||
echo "════════════════════════════════════════════════════════════════"
|
||||
echo "BUILD COMPLETE - $APP_VERSION"
|
||||
echo "✅ BUILD COMPLETE - $APP_VERSION"
|
||||
echo "════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
echo "Output: VideoTools.exe"
|
||||
|
|
@ -93,11 +93,11 @@ case "$OS" in
|
|||
echo "You can skip if FFmpeg is already installed elsewhere."
|
||||
fi
|
||||
else
|
||||
echo "Build complete: VideoTools.exe"
|
||||
echo "✓ Build complete: VideoTools.exe"
|
||||
diagnostics
|
||||
fi
|
||||
else
|
||||
echo "Build failed! (VideoTools $APP_VERSION)"
|
||||
echo "❌ Build failed! (VideoTools $APP_VERSION)"
|
||||
diagnostics
|
||||
echo ""
|
||||
echo "Help: check the Go error messages above."
|
||||
|
|
|
|||
|
|
@ -37,11 +37,10 @@ type subtitleCue struct {
|
|||
}
|
||||
|
||||
type subtitlesConfig struct {
|
||||
OutputMode string `json:"outputMode"`
|
||||
ModelPath string `json:"modelPath"`
|
||||
BackendPath string `json:"backendPath"`
|
||||
BurnOutput string `json:"burnOutput"`
|
||||
TimeOffset float64 `json:"timeOffset"`
|
||||
OutputMode string `json:"outputMode"`
|
||||
ModelPath string `json:"modelPath"`
|
||||
BackendPath string `json:"backendPath"`
|
||||
BurnOutput string `json:"burnOutput"`
|
||||
}
|
||||
|
||||
func defaultSubtitlesConfig() subtitlesConfig {
|
||||
|
|
@ -86,7 +85,6 @@ func (s *appState) applySubtitlesConfig(cfg subtitlesConfig) {
|
|||
s.subtitleModelPath = cfg.ModelPath
|
||||
s.subtitleBackendPath = cfg.BackendPath
|
||||
s.subtitleBurnOutput = cfg.BurnOutput
|
||||
s.subtitleTimeOffset = cfg.TimeOffset
|
||||
}
|
||||
|
||||
func (s *appState) persistSubtitlesConfig() {
|
||||
|
|
@ -95,7 +93,6 @@ func (s *appState) persistSubtitlesConfig() {
|
|||
ModelPath: s.subtitleModelPath,
|
||||
BackendPath: s.subtitleBackendPath,
|
||||
BurnOutput: s.subtitleBurnOutput,
|
||||
TimeOffset: s.subtitleTimeOffset,
|
||||
}
|
||||
if err := savePersistedSubtitlesConfig(cfg); err != nil {
|
||||
logging.Debug(logging.CatSystem, "failed to persist subtitles config: %v", err)
|
||||
|
|
@ -138,14 +135,14 @@ func buildSubtitlesView(state *appState) fyne.CanvasObject {
|
|||
bottomBar := moduleFooter(subtitlesColor, layout.NewSpacer(), state.statsBar)
|
||||
|
||||
videoEntry := widget.NewEntry()
|
||||
videoEntry.SetPlaceHolder("Video file path")
|
||||
videoEntry.SetPlaceHolder("Video file path (drag and drop works here)")
|
||||
videoEntry.SetText(state.subtitleVideoPath)
|
||||
videoEntry.OnChanged = func(val string) {
|
||||
state.subtitleVideoPath = strings.TrimSpace(val)
|
||||
}
|
||||
|
||||
subtitleEntry := widget.NewEntry()
|
||||
subtitleEntry.SetPlaceHolder("Subtitle file (.srt or .vtt)")
|
||||
subtitleEntry.SetPlaceHolder("Subtitle file path (.srt or .vtt)")
|
||||
subtitleEntry.SetText(state.subtitleFilePath)
|
||||
subtitleEntry.OnChanged = func(val string) {
|
||||
state.subtitleFilePath = strings.TrimSpace(val)
|
||||
|
|
@ -344,71 +341,11 @@ func buildSubtitlesView(state *appState) fyne.CanvasObject {
|
|||
})
|
||||
applyBtn.Importance = widget.HighImportance
|
||||
|
||||
browseVideoBtn := widget.NewButton("Browse", func() {
|
||||
dialog.ShowFileOpen(func(file fyne.URIReadCloser, err error) {
|
||||
if err != nil || file == nil {
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
path := file.URI().Path()
|
||||
state.subtitleVideoPath = path
|
||||
videoEntry.SetText(path)
|
||||
}, state.window)
|
||||
})
|
||||
|
||||
browseSubtitleBtn := widget.NewButton("Browse", func() {
|
||||
dialog.ShowFileOpen(func(file fyne.URIReadCloser, err error) {
|
||||
if err != nil || file == nil {
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
path := file.URI().Path()
|
||||
if err := state.loadSubtitleFile(path); err != nil {
|
||||
state.setSubtitleStatus(err.Error())
|
||||
return
|
||||
}
|
||||
subtitleEntry.SetText(path)
|
||||
rebuildCues()
|
||||
}, state.window)
|
||||
})
|
||||
|
||||
offsetEntry := widget.NewEntry()
|
||||
offsetEntry.SetPlaceHolder("0.0")
|
||||
offsetEntry.SetText(fmt.Sprintf("%.2f", state.subtitleTimeOffset))
|
||||
offsetEntry.OnChanged = func(val string) {
|
||||
if offset, err := strconv.ParseFloat(strings.TrimSpace(val), 64); err == nil {
|
||||
state.subtitleTimeOffset = offset
|
||||
state.persistSubtitlesConfig()
|
||||
}
|
||||
}
|
||||
|
||||
applyOffsetBtn := widget.NewButton("Apply Offset", func() {
|
||||
state.applySubtitleTimeOffset(state.subtitleTimeOffset)
|
||||
})
|
||||
applyOffsetBtn.Importance = widget.HighImportance
|
||||
|
||||
offsetPlus1Btn := widget.NewButton("+1s", func() {
|
||||
state.applySubtitleTimeOffset(1.0)
|
||||
})
|
||||
|
||||
offsetMinus1Btn := widget.NewButton("-1s", func() {
|
||||
state.applySubtitleTimeOffset(-1.0)
|
||||
})
|
||||
|
||||
offsetPlus01Btn := widget.NewButton("+0.1s", func() {
|
||||
state.applySubtitleTimeOffset(0.1)
|
||||
})
|
||||
|
||||
offsetMinus01Btn := widget.NewButton("-0.1s", func() {
|
||||
state.applySubtitleTimeOffset(-0.1)
|
||||
})
|
||||
|
||||
applyControls := func() {
|
||||
outputModeSelect.SetSelected(state.subtitleOutputMode)
|
||||
backendEntry.SetText(state.subtitleBackendPath)
|
||||
modelEntry.SetText(state.subtitleModelPath)
|
||||
outputEntry.SetText(state.subtitleBurnOutput)
|
||||
offsetEntry.SetText(fmt.Sprintf("%.2f", state.subtitleTimeOffset))
|
||||
}
|
||||
|
||||
loadCfgBtn := widget.NewButton("Load Config", func() {
|
||||
|
|
@ -431,7 +368,6 @@ func buildSubtitlesView(state *appState) fyne.CanvasObject {
|
|||
ModelPath: state.subtitleModelPath,
|
||||
BackendPath: state.subtitleBackendPath,
|
||||
BurnOutput: state.subtitleBurnOutput,
|
||||
TimeOffset: state.subtitleTimeOffset,
|
||||
}
|
||||
if err := savePersistedSubtitlesConfig(cfg); err != nil {
|
||||
dialog.ShowError(fmt.Errorf("failed to save config: %w", err), state.window)
|
||||
|
|
@ -449,25 +385,16 @@ func buildSubtitlesView(state *appState) fyne.CanvasObject {
|
|||
|
||||
left := container.NewVBox(
|
||||
widget.NewLabelWithStyle("Sources", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
container.NewBorder(nil, nil, nil, browseVideoBtn, ui.NewDroppable(videoEntry, handleDrop)),
|
||||
container.NewBorder(nil, nil, nil, browseSubtitleBtn, ui.NewDroppable(subtitleEntry, handleDrop)),
|
||||
widget.NewSeparator(),
|
||||
widget.NewLabelWithStyle("Timing Adjustment", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
widget.NewLabel("Shift all subtitle times by offset (seconds):"),
|
||||
offsetEntry,
|
||||
container.NewHBox(offsetMinus1Btn, offsetMinus01Btn, offsetPlus01Btn, offsetPlus1Btn),
|
||||
applyOffsetBtn,
|
||||
widget.NewSeparator(),
|
||||
ui.NewDroppable(videoEntry, handleDrop),
|
||||
ui.NewDroppable(subtitleEntry, handleDrop),
|
||||
widget.NewLabelWithStyle("Offline Speech-to-Text (whisper.cpp)", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
backendEntry,
|
||||
modelEntry,
|
||||
container.NewHBox(generateBtn),
|
||||
widget.NewSeparator(),
|
||||
widget.NewLabelWithStyle("Output", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
outputModeSelect,
|
||||
outputEntry,
|
||||
applyBtn,
|
||||
widget.NewSeparator(),
|
||||
widget.NewLabelWithStyle("Status", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
statusLabel,
|
||||
widget.NewSeparator(),
|
||||
|
|
@ -488,8 +415,7 @@ func buildSubtitlesView(state *appState) fyne.CanvasObject {
|
|||
rebuildCues()
|
||||
|
||||
content := container.NewGridWithColumns(2, left, right)
|
||||
droppableContent := ui.NewDroppable(content, handleDrop)
|
||||
return container.NewBorder(topBar, bottomBar, nil, nil, droppableContent)
|
||||
return container.NewBorder(topBar, bottomBar, nil, nil, content)
|
||||
}
|
||||
|
||||
func (s *appState) setSubtitleStatus(msg string) {
|
||||
|
|
@ -536,11 +462,7 @@ func (s *appState) handleSubtitlesModuleDrop(items []fyne.URI) {
|
|||
s.setSubtitleStatus(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh the view to show the loaded files
|
||||
if s.active == "subtitles" {
|
||||
s.showSubtitlesView()
|
||||
}
|
||||
s.showSubtitlesView()
|
||||
}
|
||||
|
||||
func (s *appState) loadSubtitleFile(path string) error {
|
||||
|
|
@ -577,27 +499,6 @@ func (s *appState) saveSubtitleFile(path string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *appState) applySubtitleTimeOffset(offsetSeconds float64) {
|
||||
if len(s.subtitleCues) == 0 {
|
||||
s.setSubtitleStatus("No subtitle cues to adjust")
|
||||
return
|
||||
}
|
||||
for i := range s.subtitleCues {
|
||||
s.subtitleCues[i].Start += offsetSeconds
|
||||
s.subtitleCues[i].End += offsetSeconds
|
||||
if s.subtitleCues[i].Start < 0 {
|
||||
s.subtitleCues[i].Start = 0
|
||||
}
|
||||
if s.subtitleCues[i].End < 0 {
|
||||
s.subtitleCues[i].End = 0
|
||||
}
|
||||
}
|
||||
if s.subtitleCuesRefresh != nil {
|
||||
s.subtitleCuesRefresh()
|
||||
}
|
||||
s.setSubtitleStatus(fmt.Sprintf("Applied %.2fs offset to %d subtitle cues", offsetSeconds, len(s.subtitleCues)))
|
||||
}
|
||||
|
||||
func (s *appState) generateSubtitlesFromSpeech() {
|
||||
videoPath := strings.TrimSpace(s.subtitleVideoPath)
|
||||
if videoPath == "" {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user