Compare commits
2 Commits
b41e41e5ad
...
1051329763
| Author | SHA1 | Date | |
|---|---|---|---|
| 1051329763 | |||
| 8f73913817 |
|
|
@ -9,6 +9,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/logging"
|
||||
"git.leaktechnologies.dev/stu/VideoTools/internal/utils"
|
||||
)
|
||||
|
||||
// HardwareInfo contains system hardware information
|
||||
|
|
@ -103,6 +104,7 @@ func detectCPULinux() (model, mhz string) {
|
|||
func detectCPUWindows() (model, mhz string) {
|
||||
// Use wmic to get CPU info
|
||||
cmd := exec.Command("wmic", "cpu", "get", "name,maxclockspeed")
|
||||
utils.ApplyNoWindow(cmd) // Hide command window on Windows
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
logging.Debug(logging.CatSystem, "failed to run wmic cpu: %v", err)
|
||||
|
|
@ -208,6 +210,7 @@ func detectGPULinux() (model, driver string) {
|
|||
func detectGPUWindows() (model, driver string) {
|
||||
// Use nvidia-smi if available (NVIDIA GPUs)
|
||||
cmd := exec.Command("nvidia-smi", "--query-gpu=name,driver_version", "--format=csv,noheader")
|
||||
utils.ApplyNoWindow(cmd) // Hide command window on Windows
|
||||
output, err := cmd.Output()
|
||||
if err == nil {
|
||||
parts := strings.Split(strings.TrimSpace(string(output)), ",")
|
||||
|
|
@ -220,21 +223,41 @@ func detectGPUWindows() (model, driver string) {
|
|||
|
||||
// Try wmic for generic GPU info
|
||||
cmd = exec.Command("wmic", "path", "win32_VideoController", "get", "name,driverversion")
|
||||
utils.ApplyNoWindow(cmd) // Hide command window on Windows
|
||||
output, err = cmd.Output()
|
||||
if err == nil {
|
||||
lines := strings.Split(string(output), "\n")
|
||||
if len(lines) >= 2 {
|
||||
// Skip header, get first GPU
|
||||
line := strings.TrimSpace(lines[1])
|
||||
if line != "" {
|
||||
// Parse: Name DriverVersion
|
||||
re := regexp.MustCompile(`^(.+?)\s+(\S+)$`)
|
||||
matches := re.FindStringSubmatch(line)
|
||||
if len(matches) == 3 {
|
||||
model = strings.TrimSpace(matches[1])
|
||||
driver = strings.TrimSpace(matches[2])
|
||||
return model, driver
|
||||
}
|
||||
// Iterate through all video controllers, skip virtual/non-physical adapters
|
||||
for i, line := range lines {
|
||||
if i == 0 { // Skip header
|
||||
continue
|
||||
}
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Filter out virtual/software adapters
|
||||
lineLower := strings.ToLower(line)
|
||||
if strings.Contains(lineLower, "virtual") ||
|
||||
strings.Contains(lineLower, "microsoft basic") ||
|
||||
strings.Contains(lineLower, "remote") ||
|
||||
strings.Contains(lineLower, "vnc") ||
|
||||
strings.Contains(lineLower, "parsec") ||
|
||||
strings.Contains(lineLower, "teamviewer") {
|
||||
logging.Debug(logging.CatSystem, "skipping virtual GPU: %s", line)
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse: Name DriverVersion
|
||||
// Use flexible regex to handle varying whitespace
|
||||
re := regexp.MustCompile(`^(.+?)\s+(\S+)$`)
|
||||
matches := re.FindStringSubmatch(line)
|
||||
if len(matches) == 3 {
|
||||
model = strings.TrimSpace(matches[1])
|
||||
driver = strings.TrimSpace(matches[2])
|
||||
logging.Debug(logging.CatSystem, "detected physical GPU: %s (driver: %s)", model, driver)
|
||||
return model, driver
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -316,6 +339,7 @@ func detectRAMLinux() (readable string, mb uint64) {
|
|||
|
||||
func detectRAMWindows() (readable string, mb uint64) {
|
||||
cmd := exec.Command("wmic", "computersystem", "get", "totalphysicalmemory")
|
||||
utils.ApplyNoWindow(cmd) // Hide command window on Windows
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
logging.Debug(logging.CatSystem, "failed to run wmic computersystem: %v", err)
|
||||
|
|
|
|||
29
main.go
29
main.go
|
|
@ -6235,6 +6235,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
}
|
||||
outputHint := widget.NewLabel(fmt.Sprintf("Output file: %s", state.convert.OutputFile()))
|
||||
outputHint.Wrapping = fyne.TextWrapWord
|
||||
// Wrap hint in padded container to ensure proper text wrapping in narrow windows
|
||||
outputHintContainer := container.NewPadded(outputHint)
|
||||
|
||||
// DVD-specific aspect ratio selector (only shown for DVD formats)
|
||||
dvdAspectSelect := widget.NewSelect([]string{"4:3", "16:9"}, func(value string) {
|
||||
|
|
@ -6633,6 +6635,9 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
}
|
||||
targetAspectSelect.SetSelected(state.convert.OutputAspect)
|
||||
targetAspectHint := widget.NewLabel("Pick desired output aspect (default Source).")
|
||||
targetAspectHint.Wrapping = fyne.TextWrapWord
|
||||
// Wrap hint in padded container to ensure proper text wrapping in narrow windows
|
||||
targetAspectHintContainer := container.NewPadded(targetAspectHint)
|
||||
|
||||
aspectOptions := widget.NewRadioGroup([]string{"Auto", "Crop", "Letterbox", "Pillarbox", "Blur Fill", "Stretch"}, func(value string) {
|
||||
logging.Debug(logging.CatUI, "aspect handling set to %s", value)
|
||||
|
|
@ -6776,6 +6781,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
// Encoder Preset with hint
|
||||
encoderPresetHint := widget.NewLabel("")
|
||||
encoderPresetHint.Wrapping = fyne.TextWrapWord
|
||||
// Wrap hint in padded container to ensure proper text wrapping in narrow windows
|
||||
encoderPresetHintContainer := container.NewPadded(encoderPresetHint)
|
||||
|
||||
updateEncoderPresetHint := func(preset string) {
|
||||
var hint string
|
||||
|
|
@ -7458,6 +7465,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
|
||||
encodingHint := widget.NewLabel("")
|
||||
encodingHint.Wrapping = fyne.TextWrapWord
|
||||
// Wrap hint in padded container to ensure proper text wrapping in narrow windows
|
||||
encodingHintContainer := container.NewPadded(encodingHint)
|
||||
|
||||
applyBitratePreset = func(label string) {
|
||||
preset, ok := bitratePresetLookup[label]
|
||||
|
|
@ -7612,6 +7621,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
// Frame Rate with hint
|
||||
frameRateHint := widget.NewLabel("")
|
||||
frameRateHint.Wrapping = fyne.TextWrapWord
|
||||
// Wrap hint in padded container to ensure proper text wrapping in narrow windows
|
||||
frameRateHintContainer := container.NewPadded(frameRateHint)
|
||||
|
||||
updateFrameRateHint := func() {
|
||||
if src == nil {
|
||||
|
|
@ -7694,6 +7705,8 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
// Hardware Acceleration with hint
|
||||
hwAccelHint := widget.NewLabel("Auto picks the best GPU path; if encode fails, switch to none (software).")
|
||||
hwAccelHint.Wrapping = fyne.TextWrapWord
|
||||
// Wrap hint in padded container to ensure proper text wrapping in narrow windows
|
||||
hwAccelHintContainer := container.NewPadded(hwAccelHint)
|
||||
hwAccelSelect := widget.NewSelect([]string{"auto", "none", "nvenc", "amf", "vaapi", "qsv", "videotoolbox"}, func(value string) {
|
||||
state.convert.HardwareAccel = value
|
||||
logging.Debug(logging.CatUI, "hardware accel set to %s", value)
|
||||
|
|
@ -8002,7 +8015,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
dvdAspectBox, // DVD options appear here when DVD format selected
|
||||
widget.NewLabelWithStyle("Output Name", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
outputEntry,
|
||||
outputHint,
|
||||
outputHintContainer,
|
||||
widget.NewSeparator(),
|
||||
simpleEncodingSection,
|
||||
widget.NewLabelWithStyle("Target Resolution", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
|
|
@ -8012,7 +8025,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
motionInterpCheck,
|
||||
widget.NewLabelWithStyle("Target Aspect Ratio", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
targetAspectSelectSimple,
|
||||
targetAspectHint,
|
||||
targetAspectHintContainer,
|
||||
layout.NewSpacer(),
|
||||
)
|
||||
|
||||
|
|
@ -8023,25 +8036,25 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
videoCodecSelect,
|
||||
widget.NewLabelWithStyle("Encoder Preset (speed vs quality)", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
encoderPresetSelect,
|
||||
encoderPresetHint,
|
||||
encoderPresetHintContainer,
|
||||
qualitySectionAdv,
|
||||
widget.NewLabelWithStyle("Bitrate Mode", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
bitrateModeSelect,
|
||||
crfContainer,
|
||||
bitrateContainer,
|
||||
targetSizeContainer,
|
||||
encodingHint,
|
||||
encodingHintContainer,
|
||||
widget.NewLabelWithStyle("Target Resolution", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
resolutionSelect,
|
||||
widget.NewLabelWithStyle("Frame Rate", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
frameRateSelect,
|
||||
frameRateHint,
|
||||
frameRateHintContainer,
|
||||
motionInterpCheck,
|
||||
widget.NewLabelWithStyle("Pixel Format", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
pixelFormatSelect,
|
||||
widget.NewLabelWithStyle("Hardware Acceleration", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
hwAccelSelect,
|
||||
hwAccelHint,
|
||||
hwAccelHintContainer,
|
||||
twoPassCheck,
|
||||
)
|
||||
|
||||
|
|
@ -8064,7 +8077,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
dvdAspectBox, // DVD options appear here when DVD format selected
|
||||
widget.NewLabelWithStyle("Output Name", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
outputEntry,
|
||||
outputHint,
|
||||
outputHintContainer,
|
||||
coverDisplay,
|
||||
widget.NewSeparator(),
|
||||
advancedVideoEncodingBlock,
|
||||
|
|
@ -8073,7 +8086,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
widget.NewLabelWithStyle("═══ ASPECT RATIO ═══", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
|
||||
widget.NewLabelWithStyle("Target Aspect Ratio", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
targetAspectSelect,
|
||||
targetAspectHint,
|
||||
targetAspectHintContainer,
|
||||
aspectBox,
|
||||
widget.NewSeparator(),
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user