代码拉取完成,页面将自动刷新
同步操作将从 全糖咖啡/B站缓存转视频工具-Golang 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
package main
import (
"encoding/json"
"fmt"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/widget"
"io/ioutil"
"os"
"path/filepath"
"strconv"
)
type softwareSetting struct {
// these items are used for global settings load
SourcePath string `json:"sourcePath"`
TargetPath string `json:"targetPath"`
OverrideOutput bool `json:"overrideOutput"`
OutputFormat string `json:"outputFormat"`
OutputAudioFormat string `json:"outputAudioFormat"`
OutputNameFormat string `json:"outputNameFormat"`
OnlyAudio bool `json:"only_audio"`
Bitrate int64 `json:"bitrate"`
DiskProtect int64 `json:"diskProtect"`
}
var cp string
var (
sourcePathEntry = &widget.Entry{}
targetPathEntry = &widget.Entry{}
outputNameFormatEntry = &widget.Entry{}
bitrateEntry = &widget.Entry{}
diskProtectEntry = &widget.Entry{}
overrideOutputCheck = &widget.Check{}
onlyAudioCheck = &widget.Check{}
outputFormatRadioGroup = &widget.Select{}
outputAudioFormatRadioGroup = &widget.Select{}
)
func (s *softwareSetting) load() {
err := s.loadFromFile(cp)
if err != nil {
fyne.LogError("SoftwareSetting load error:", err)
return
}
// ui回显
sourcePathEntry.SetText(s.SourcePath)
sourcePathEntry.Refresh()
targetPathEntry.SetText(s.TargetPath)
targetPathEntry.Refresh()
if s.OutputNameFormat == "" {
s.OutputNameFormat = "$[page]-$[part]"
}
outputNameFormatEntry.SetText(s.OutputNameFormat)
outputNameFormatEntry.Refresh()
overrideOutputCheck.SetChecked(s.OverrideOutput)
overrideOutputCheck.Refresh()
onlyAudioCheck.SetChecked(s.OnlyAudio)
onlyAudioCheck.Refresh()
if s.OnlyAudio {
outputFormatRadioGroup.Disable()
outputAudioFormatRadioGroup.Enable()
} else {
outputFormatRadioGroup.Enable()
outputAudioFormatRadioGroup.Disable()
}
if s.OutputFormat != "" {
outputFormatRadioGroup.SetSelected(s.OutputFormat)
} else {
outputFormatRadioGroup.SetSelectedIndex(0)
}
if s.OutputAudioFormat != "" {
outputAudioFormatRadioGroup.SetSelected(s.OutputAudioFormat)
} else {
outputAudioFormatRadioGroup.SetSelectedIndex(0)
}
if s.Bitrate == 0 {
s.Bitrate = 100
}
bitrateEntry.SetText(strconv.FormatInt(s.Bitrate, 10))
if s.DiskProtect == 0 {
s.DiskProtect = 10
} else if s.DiskProtect == -1 {
s.DiskProtect = 1
}
diskProtectEntry.SetText(strconv.FormatInt(s.DiskProtect, 10))
}
func (s *softwareSetting) loadFromFile(path string) error {
file, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
err := os.MkdirAll(filepath.Dir(path), 0700)
if err != nil {
return err
}
err = s.save()
if err != nil {
return err
}
file, err = os.Open(path)
}
return err
}
decode := json.NewDecoder(file)
return decode.Decode(&s)
}
func (s *softwareSetting) save() error {
s.SourcePath = sourcePathEntry.Text
s.TargetPath = targetPathEntry.Text
if outputNameFormatEntry.Text == "" {
outputNameFormatEntry.SetText("$[page]-$[part]")
}
s.OutputNameFormat = outputNameFormatEntry.Text
return s.saveToFile()
}
func (s *softwareSetting) saveToFile() error {
err := os.MkdirAll(filepath.Dir(cp), 0700)
if err != nil { // this is not an exists error according to docs
return err
}
data, err := json.Marshal(&s)
if err != nil {
return err
}
return ioutil.WriteFile(cp, data, 0644)
}
func NewSoftwareSetting() *softwareSetting {
cp = "config.json"
s := &softwareSetting{}
s.load()
return s
}
func (s *softwareSetting) getFolderPath(win fyne.Window, callback func(str string)) func() {
return func() {
folderDialog := dialog.NewFolderOpen(func(list fyne.ListableURI, err error) {
if list != nil {
callback(list.Path())
}
}, win)
folderDialog.SetConfirmText("选择")
folderDialog.SetDismissText("取消")
testData, _ := filepath.Abs("")
dir, err := storage.ListerForURI(storage.NewFileURI(testData))
if err != nil {
return
}
folderDialog.SetLocation(dir)
folderDialog.Show()
}
}
func (s *softwareSetting) GetMenu(win fyne.Window) fyne.CanvasObject {
sourcePathEntry = widget.NewEntry()
sourcePathLabel := widget.NewLabel("缓存路径")
sourcePathSetting := container.NewBorder(nil, nil, nil, widget.NewButton("修改", s.getFolderPath(win, func(str string) {
sourcePathEntry.SetText(str)
sourcePathEntry.Refresh()
s.SourcePath = str
})), sourcePathEntry)
targetPathEntry = widget.NewEntry()
targetPathLabel := widget.NewLabel("保存路径")
targetPathSetting := container.NewBorder(nil, nil, nil, widget.NewButton("修改", s.getFolderPath(win, func(str string) {
targetPathEntry.SetText(str)
targetPathEntry.Refresh()
s.TargetPath = str
})), targetPathEntry)
outputNameFormatEntry = widget.NewEntry()
outputNameFormatEntry.SetPlaceHolder("$[page]-$[part]")
outputNameFormatLabel := widget.NewLabel("保存名称")
temp := widget.NewLabel("变量格式(默认为$[page]-$[part]):\r\n$[page]:集数\t\t$[part]:分集名称\t\t$[title]:视频名称")
outputNameFormatSetting := container.NewBorder(nil, temp, nil, nil, outputNameFormatEntry)
onlyAudioLabel := widget.NewLabel("仅提取音频文件")
onlyAudioCheck = widget.NewCheck("(启用后将不处理视频文件,【视频输出格式】配置项将失效)", func(b bool) {
s.OnlyAudio = b
if b {
outputFormatRadioGroup.Disable()
outputAudioFormatRadioGroup.Enable()
} else {
outputFormatRadioGroup.Enable()
outputAudioFormatRadioGroup.Disable()
}
})
outputFormatLabel := widget.NewLabel("视频输出格式")
outputFormatRadioGroup = widget.NewSelect([]string{"mp4", "avi", "mkv", "mov"}, func(value string) {
if value != "" {
s.OutputFormat = value
}
})
outputFormat := container.NewBorder(nil, nil, outputFormatRadioGroup, nil, nil)
outputAudioFormatLabel := widget.NewLabel("音频输出格式")
outputAudioFormatRadioGroup = widget.NewSelect([]string{"mp3", "aac", "wav", "flac", "ogg", "wma"}, func(value string) {
if value != "" {
s.OutputAudioFormat = value
}
})
outputAudioFormat := container.NewBorder(nil, nil, outputAudioFormatRadioGroup, nil, nil)
overrideOutputLabel := widget.NewLabel("是否覆盖保存")
overrideOutputCheck = widget.NewCheck("(启用后会覆盖上次转换完成的视频)", func(b bool) {
s.OverrideOutput = b
})
bitrateLabel := widget.NewLabel("视频码率压缩")
bitrateEntry = widget.NewEntry()
bitrateSlider := widget.NewSlider(1, 100)
bitrateSlider.Step = 1
bitrateSlider.OnChanged = func(value float64) {
//bitrateValue.SetText(fmt.Sprintf("%.0f%%", value))
tempValue, err := strconv.ParseInt(fmt.Sprintf("%.0f", value), 10, 64)
if err == nil {
// 保存该值(码率)
s.Bitrate = tempValue
bitrateEntry.SetText(strconv.FormatInt(s.Bitrate, 10))
}
}
bitrateEntry.Validator = func(text string) error {
for _, char := range text {
if char < '0' || char > '9' {
return fmt.Errorf("fail!")
}
}
tempValue, err := strconv.ParseInt(text, 10, 64)
if err == nil {
// 判断边界
if tempValue < 1 {
tempValue = 1
} else if tempValue > 100 {
tempValue = 100
}
// 保存该值(码率)
s.Bitrate = tempValue
bitrateSlider.SetValue(float64(s.Bitrate))
return nil
} else {
return err
}
}
bitrate := container.NewBorder(nil, nil, nil, bitrateEntry, bitrateSlider)
diskProtectEntry = widget.NewEntry()
diskProtectEntry.Resize(fyne.NewSize(70, 32))
diskProtectEntry.Validator = func(text string) error {
for _, char := range text {
if char < '0' || char > '9' {
return fmt.Errorf("fail!")
}
}
tempValue, err := strconv.ParseInt(text, 10, 64)
if err == nil {
// 判断边界
if tempValue <= 0 {
tempValue = -1
}
// 保存该值(码率)
s.DiskProtect = tempValue
return nil
} else {
return err
}
}
diskProtectLabel := widget.NewLabel("磁盘空间保护")
spaceTypeLabel := widget.NewLabel("G(请填写整数,最小值为1)")
spaceTypeLabel.Move(fyne.NewPos(70, 0))
diskProtect := container.NewWithoutLayout(diskProtectEntry, spaceTypeLabel)
blank := widget.NewLabel(" ")
blankValue := widget.NewLabel(" ")
settingGroup := container.New(
layout.NewFormLayout(),
sourcePathLabel,
sourcePathSetting,
targetPathLabel,
targetPathSetting,
outputNameFormatLabel,
outputNameFormatSetting,
diskProtectLabel,
diskProtect,
onlyAudioLabel,
onlyAudioCheck,
outputFormatLabel,
outputFormat,
outputAudioFormatLabel,
outputAudioFormat,
overrideOutputLabel,
overrideOutputCheck,
bitrateLabel,
bitrate,
blank,
blankValue)
btn := container.NewBorder(nil, nil, layout.NewSpacer(), layout.NewSpacer(), widget.NewButton("保存", func() {
err := s.save()
if err != nil {
return
}
s.load()
win.Close()
}))
cnt := container.NewVBox(settingGroup, btn)
s.load()
return cnt
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。