167 lines
3.8 KiB
Go
167 lines
3.8 KiB
Go
package main
|
||
|
||
import (
|
||
"encoding/csv"
|
||
"fmt"
|
||
"github.com/manifoldco/promptui"
|
||
"golang.org/x/text/encoding/simplifiedchinese"
|
||
"golang.org/x/text/transform"
|
||
"os"
|
||
"strings"
|
||
)
|
||
|
||
func getCsvInfo(dir string) (dataMap []map[string]string, title []string) {
|
||
fp := fmt.Sprintf("%s/%s/", dir, "csvfile")
|
||
entries, err := os.ReadDir(fp)
|
||
if err != nil {
|
||
panic("当前目录下未找到csvfile文件夹,请自行创建")
|
||
}
|
||
var csvFiles []string
|
||
for _, entry := range entries {
|
||
if !entry.IsDir() && strings.HasSuffix(strings.ToLower(entry.Name()), ".csv") {
|
||
csvFiles = append(csvFiles, entry.Name())
|
||
}
|
||
}
|
||
for {
|
||
prompt := promptui.Select{
|
||
Label: "请选择需要导入的csv文件: ",
|
||
Items: csvFiles,
|
||
Size: len(csvFiles),
|
||
}
|
||
_, f, err := prompt.Run()
|
||
if err != nil {
|
||
warning("Prompt failed %v\n", err)
|
||
continue
|
||
}
|
||
fp = fmt.Sprintf("%s/%s", fp, f)
|
||
break
|
||
}
|
||
return ReadCsvData(fp)
|
||
}
|
||
|
||
func ReadCsvData(fp string) (dataMap []map[string]string, title []string) {
|
||
log("正在读取CSV文件,请稍等...")
|
||
// 打开CSV文件
|
||
file, err := os.Open(fp)
|
||
if err != nil {
|
||
fatal("无法打开文件: %v", err)
|
||
}
|
||
defer file.Close()
|
||
decoder := simplifiedchinese.GBK.NewDecoder()
|
||
// 创建CSV读取器
|
||
reader := csv.NewReader(transform.NewReader(file, decoder))
|
||
// 可选:设置更宽松的解析选项
|
||
reader.LazyQuotes = true // 允许非引号包裹的字段中包含引号
|
||
// 读取所有记录
|
||
records, err := reader.ReadAll()
|
||
if err != nil {
|
||
fatal("读取CSV记录出错: %v", err)
|
||
}
|
||
if len(records) < 2 {
|
||
fatal("CSV文件至少需要两行,第一行是标题,第二行是数据")
|
||
}
|
||
// 创建map来存储数据
|
||
dataMap = make([]map[string]string, len(records))
|
||
title = records[0]
|
||
for i := 1; i < len(records); i++ {
|
||
|
||
dataMap[i-1] = make(map[string]string)
|
||
for j := 0; j < len(records[i]); j++ { // 假设第一列是唯一标识符
|
||
dataMap[i-1][title[j]] = records[i][j]
|
||
}
|
||
}
|
||
|
||
log("文件读取完毕")
|
||
return
|
||
}
|
||
|
||
func desc(video *Video) {
|
||
var d strings.Builder
|
||
tip("描述信息,请输入一段描述文字,描述文字越多,生成视频越精彩。")
|
||
input("请设置描述信息: ")
|
||
text, _ := reader.ReadString('\n')
|
||
d.WriteString(fmt.Sprintf("%s ", strings.TrimSpace(text)))
|
||
d.WriteString("--watermark ")
|
||
d.WriteString("false ")
|
||
for {
|
||
prompt := promptui.Select{
|
||
Label: "分辨率: ",
|
||
Items: []string{"480p", "720p"},
|
||
}
|
||
_, r, err := prompt.Run()
|
||
if err != nil {
|
||
warning("Prompt failed %v\n", err)
|
||
continue
|
||
}
|
||
d.WriteString("--resolution ")
|
||
d.WriteString(r)
|
||
d.WriteString(" ")
|
||
break
|
||
}
|
||
|
||
for {
|
||
prompt := promptui.Select{
|
||
Label: "视频时长(秒): ",
|
||
Items: []string{"5", "10"},
|
||
}
|
||
_, r, err := prompt.Run()
|
||
if err != nil {
|
||
warning("Prompt failed %v\n", err)
|
||
continue
|
||
}
|
||
d.WriteString("--dur ")
|
||
d.WriteString(r)
|
||
d.WriteString(" ")
|
||
break
|
||
}
|
||
tip("adaptive:根据所上传图片的比例,自动选择最合适的宽高比。")
|
||
for {
|
||
prompt := promptui.Select{
|
||
Label: "视频的宽高比例: ",
|
||
Items: []string{"adaptive", "16:9", "9:16", "4:3", "3:4", "21:9", "9:21", "1:1"},
|
||
}
|
||
_, r, err := prompt.Run()
|
||
if err != nil {
|
||
warning("Prompt failed %v\n", err)
|
||
continue
|
||
}
|
||
d.WriteString("--ratio ")
|
||
d.WriteString(r)
|
||
d.WriteString(" ")
|
||
break
|
||
}
|
||
|
||
for {
|
||
prompt := promptui.Select{
|
||
Label: "帧率: ",
|
||
Items: []string{"16", "24"},
|
||
}
|
||
_, r, err := prompt.Run()
|
||
if err != nil {
|
||
warning("Prompt failed %v\n", err)
|
||
continue
|
||
}
|
||
d.WriteString("--framepersecond ")
|
||
d.WriteString(r)
|
||
d.WriteString(" ")
|
||
break
|
||
}
|
||
|
||
for {
|
||
prompt := promptui.Select{
|
||
Label: "是否固定摄像头: ",
|
||
Items: []string{"false", "true"},
|
||
}
|
||
_, r, err := prompt.Run()
|
||
if err != nil {
|
||
warning("Prompt failed %v\n", err)
|
||
continue
|
||
}
|
||
d.WriteString("--camerafixed ")
|
||
d.WriteString(r)
|
||
d.WriteString(" ")
|
||
break
|
||
}
|
||
video.Text = d.String()
|
||
}
|