package main import ( "bufio" "context" "github.com/manifoldco/promptui" "time" "encoding/json" "fmt" "github.com/common-nighthawk/go-figure" "github.com/volcengine/volcengine-go-sdk/service/arkruntime" "github.com/volcengine/volcengine-go-sdk/service/arkruntime/model" "github.com/volcengine/volcengine-go-sdk/volcengine" "os" "strings" ) var ( reader = bufio.NewReader(os.Stdin) ) var statusMap = map[string]string{ "queued": "排队中", "running": "任务运行中", "cancelled": "取消任务", "succeeded": "任务成功", "failed": "任务失败", } type Conf struct { Key string `json:"key"` Model string `json:"model"` } type Video struct { Url string `json:"url"` Text string `json:"text"` } func setVideoInfo() *Video { var video = new(Video) img(video) desc(video) return video } var c *Conf func main() { log("正在读取配置。。。") c = getConf() success("读取配置成功!请务必保证网络通畅") client := arkruntime.NewClientWithApiKey(c.Key) video := setVideoInfo() //finish(client, video) do(client, c, video) } func do(client *arkruntime.Client, c *Conf, video *Video) { ctx := context.Background() createReq := model.CreateContentGenerationTaskRequest{ Model: c.Model, Content: []*model.CreateContentGenerationContentItem{ { // 文本提示词与参数组合 Type: model.ContentGenerationContentItemTypeText, Text: volcengine.String(video.Text), }, { // 图片URL Type: model.ContentGenerationContentItemTypeImage, ImageURL: &model.ImageURL{ URL: video.Url, //请上传可以访问的图片URL }, }, }, } createResponse, err := client.CreateContentGenerationTask(ctx, createReq) if err != nil { warning("创建视频失败: %v", err) return } success("视频正在制作中,请稍后,taskId: %s", createResponse.ID) listenTask(ctx, client, createResponse.ID, video) } func listenTask(ctx context.Context, client *arkruntime.Client, taskId string, video *Video) { var ( req = model.GetContentGenerationTaskRequest{taskId} ) for { time.Sleep(time.Second * 1) resp, err := client.GetContentGenerationTask(ctx, req) if err != nil { warning("获取视频信息失败: %v", err) continue } log(statusMap[resp.Status]) if resp.Status == "succeeded" { tip("本次消耗token: %d\n", resp.Usage.TotalTokens) success("请复制下面地址到浏览器进行下载:\n") fmt.Println(resp.Content.VideoURL) finish(client, video) } } } func finish(client *arkruntime.Client, video *Video) { prompt := promptui.Select{ Label: "", Items: []string{"退出", "重新生成", "修改设置重新生成"}, } _, r, err := prompt.Run() if err != nil { warning("Prompt failed %v\n", err) return } switch r { case "退出": prompt1 := promptui.Select{ Label: "是否退出", Items: []string{"否", "是"}, } _, q, _err := prompt1.Run() if _err != nil { warning("Prompt failed %v\n", err) return } if q == "是" { tip("最后祝您身体健康,再见") exit() } else { finish(client, video) } case "重新生成": do(client, c, video) case "修改设置重新生成": video = setVideoInfo() do(client, c, video) } } func getConf() *Conf { wd, err := os.Getwd() fp := fmt.Sprintf("%s/%s", wd, "ex_pic_to_video_conf") if err != nil { fatal("获取当前路径失败") exit() } file, err := os.Open(fp) if err != nil { if !os.IsNotExist(err) { os.Remove(fp) } return cConf(fp) } defer file.Close() content, err := os.ReadFile(fp) if err != nil { fatal("获取配置信息失败") exit() } var ( pwd string conf = new(Conf) ) for { input("请输入访问密码: ") pwd, _ = reader.ReadString('\n') cjson, err := decrypt([]byte(padToLength(strings.TrimSpace(pwd), 16, ' ')), string(content)) if err != nil { warning("密码错误") continue } err = json.Unmarshal([]byte(cjson), &conf) if err != nil { warning("配置读取失败") } break } return conf } func cConf(fp string) *Conf { conf := new(Conf) log("进入初始化配置向导") log("----------------------") input("请设置key: ") k, _ := reader.ReadString('\n') conf.Key = strings.TrimSpace(k) if conf.Key == "lsxd2025" { conf.Key = "" conf.Model = "" myFigure := figure.NewFigure("LSXD", "", true) myFigure.Print() success("欢迎进入调试模式!") return conf } input("请设置model: ") m, _ := reader.ReadString('\n') conf.Model = strings.TrimSpace(m) var ( pwd string ) for { input("请设置访问密码(密码长度请小于16位): ") pwd, _ = reader.ReadString('\n') if len(strings.TrimSpace(pwd)) > 16 { warning("密码长度请小于16位") continue } break } cjson, _ := json.Marshal(conf) pad := padToLength(strings.TrimSpace(pwd), 16, ' ') en, e := encrypt([]byte(pad), string(cjson)) if e != nil { fatal("设置失败,程序退出:%v", e) exit() } if err := os.WriteFile(fp, []byte(en), 0666); err != nil { fatal("写入失败,程序退出") exit() } return conf } func exit() { os.Exit(1) }