feat: FFmpeg GUI desktop application
Wails v2 + Vue3 + Go project with: - Encode/Remux/Subtitle burn with hardware acceleration - Real-time progress with ffmpeg stderr parsing (\r delimiter handling) - Task queue with cancel support - Per-task log viewer with color-coded output - Custom frameless window with resize support - Dark/light theme toggle - Hardware encoder detection (NVENC/QSV/AMF)
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
package hwaccel
|
||||
|
||||
import (
|
||||
"ffmpeg-gui/internal/ffmpeg"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// HWEncoder represents a detected hardware encoder.
|
||||
type HWEncoder struct {
|
||||
Name string `json:"name"` // e.g., "h264_nvenc"
|
||||
Label string `json:"label"` // e.g., "NVIDIA NVENC H.264"
|
||||
Type string `json:"type"` // "nvidia", "intel", "amd", "software"
|
||||
Codec string `json:"codec"` // "h264", "hevc", "av1"
|
||||
Available bool `json:"available"`
|
||||
}
|
||||
|
||||
// Accelerator represents a detected hardware acceleration method.
|
||||
type Accelerator struct {
|
||||
Name string `json:"name"`
|
||||
Available bool `json:"available"`
|
||||
}
|
||||
|
||||
// Detector detects hardware acceleration capabilities.
|
||||
type Detector struct {
|
||||
exec *ffmpeg.Executor
|
||||
}
|
||||
|
||||
// NewDetector creates a new hardware detector.
|
||||
func NewDetector(exec *ffmpeg.Executor) *Detector {
|
||||
return &Detector{exec: exec}
|
||||
}
|
||||
|
||||
// knownEncoders defines all hardware encoders to check for.
|
||||
var knownEncoders = []struct {
|
||||
Name string
|
||||
Type string
|
||||
Codec string
|
||||
Label string
|
||||
}{
|
||||
// NVIDIA NVENC
|
||||
{"h264_nvenc", "nvidia", "h264", "NVIDIA NVENC H.264"},
|
||||
{"hevc_nvenc", "nvidia", "hevc", "NVIDIA NVENC H.265/HEVC"},
|
||||
{"av1_nvenc", "nvidia", "av1", "NVIDIA NVENC AV1"},
|
||||
// Intel QSV
|
||||
{"h264_qsv", "intel", "h264", "Intel QSV H.264"},
|
||||
{"hevc_qsv", "intel", "hevc", "Intel QSV H.265/HEVC"},
|
||||
{"av1_qsv", "intel", "av1", "Intel QSV AV1"},
|
||||
// AMD AMF
|
||||
{"h264_amf", "amd", "h264", "AMD AMF H.264"},
|
||||
{"hevc_amf", "amd", "hevc", "AMD AMF H.265/HEVC"},
|
||||
{"av1_amf", "amd", "av1", "AMD AMF AV1"},
|
||||
}
|
||||
|
||||
// DetectEncoders detects available hardware encoders.
|
||||
func (d *Detector) DetectEncoders() ([]HWEncoder, error) {
|
||||
out, err := d.exec.RunSync("-encoders")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var encoders []HWEncoder
|
||||
for _, ke := range knownEncoders {
|
||||
available := strings.Contains(out, ke.Name)
|
||||
encoders = append(encoders, HWEncoder{
|
||||
Name: ke.Name,
|
||||
Label: ke.Label,
|
||||
Type: ke.Type,
|
||||
Codec: ke.Codec,
|
||||
Available: available,
|
||||
})
|
||||
}
|
||||
return encoders, nil
|
||||
}
|
||||
|
||||
// DetectAccelerators detects available hardware acceleration methods.
|
||||
func (d *Detector) DetectAccelerators() ([]Accelerator, error) {
|
||||
out, err := d.exec.RunSync("-hwaccels")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
known := []string{"cuda", "d3d11va", "dxva2", "qsv", "vulkan"}
|
||||
|
||||
var accels []Accelerator
|
||||
for _, k := range known {
|
||||
accels = append(accels, Accelerator{
|
||||
Name: k,
|
||||
Available: strings.Contains(out, k),
|
||||
})
|
||||
}
|
||||
return accels, nil
|
||||
}
|
||||
Reference in New Issue
Block a user