You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Go调用ffprobe获取HLS时长出现exit status 1错误求助

问题修复方案

核心错误原因

exit status 1 是因为 ffprobe 执行失败,最关键的问题是请求头参数的引号错误,同时还有几处逻辑和功能缺失问题,逐一修正如下:


1. 修正请求头参数

GetDurationScript 里的 -headers 参数带了多余的双引号,exec.Command 会将每个参数作为独立项传递,不需要手动加引号,否则 ffprobe 会把带引号的字符串当作 header 的一部分,导致授权验证失败。

错误写法:

`"Authorization: YOUR_TOKEN"`

正确写法:

"Authorization: YOUR_TOKEN"

2. 修复1080p文件查找逻辑

原循环如果遍历完所有文件都没找到1080p的,会直接取最后一个文件,导致后续处理错误,需要添加判断逻辑:

found := false
var targetFile *models.ProcessedFiles
for _, file := range files {
    if file.Quality == "1080p" {
        targetFile = file
        found = true
        break
    }
}
if !found {
    return models.FileResponse{}, errors.New("1080p quality file not found")
}

3. 捕获并解析ffprobe输出

原代码只是重定向输出,没有获取时长数据,需要捕获stdout并解析JSON结果:

首先定义一个结构体来解析ffprobe的输出:

type FFProbeDuration struct {
    Format struct {
        Duration string `json:"duration"`
    } `json:"format"`
}

然后修改执行ffprobe的逻辑,捕获stdout:

var stdout bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr

err = cmd.Run()
if err != nil {
    return models.FileResponse{}, fmt.Errorf("ffprobe failed: %w, stderr: %s", err, stderr.String())
}

var durationResp FFProbeDuration
err = json.Unmarshal(stdout.Bytes(), &durationResp)
if err != nil {
    return models.FileResponse{}, fmt.Errorf("failed to parse ffprobe output: %w", err)
}

// 这里可以将durationResp.Format.Duration转换成float64或者直接使用字符串
fmt.Printf("Video duration: %s seconds\n", durationResp.Format.Duration)

4. 移除冗余代码

原代码中调用了 os.Getwd() 但没有使用结果,直接删除即可。


完整修正后的代码

import (
    "bytes"
    "encoding/json"
    "errors"
    "fmt"
    "os/exec"

    "your-module-path/models"
    "your-module-path/utils"
    "go.uber.org/zap"
)

type FFProbeDuration struct {
    Format struct {
        Duration string `json:"duration"`
    } `json:"format"`
}

func (i *ImageGenerationService) GenerateImages(movieID int) (models.FileResponse, error) {
    if _, err := exec.LookPath("ffprobe"); err != nil {
        return models.FileResponse{}, errors.New("video.Init: ffprobe was not found in your PATH")
    }

    files, err := i.GetVideoFiles(movieID)
    if err != nil {
        i.logger.Warn("failed to get files", zap.Error(err))
        return models.FileResponse{}, err
    }

    // 查找1080p文件
    found := false
    var targetFile *models.ProcessedFiles
    for _, file := range files {
        if file.Quality == "1080p" {
            targetFile = file
            found = true
            break
        }
    }
    if !found {
        return models.FileResponse{}, errors.New("1080p quality file not found")
    }

    args := utils.GetDurationScript(targetFile.Filename)
    cmd := exec.Command("ffprobe", args...)

    var stdout bytes.Buffer
    var stderr bytes.Buffer
    cmd.Stdout = &stdout
    cmd.Stderr = &stderr

    err = cmd.Run()
    if err != nil {
        return models.FileResponse{}, fmt.Errorf("ffprobe execution failed: %w, details: %s", err, stderr.String())
    }

    // 解析时长
    var durationResp FFProbeDuration
    err = json.Unmarshal(stdout.Bytes(), &durationResp)
    if err != nil {
        return models.FileResponse{}, fmt.Errorf("parse ffprobe output failed: %w", err)
    }

    // 这里可以根据需要处理时长,比如转换为float64
    // duration, _ := strconv.ParseFloat(durationResp.Format.Duration, 64)

    return models.FileResponse{}, nil
}

func GetDurationScript(hls string) []string {
    return []string{
        "-v",
        "quiet",
        "-show_entries",
        "format=duration",
        "-print_format",
        "json",
        "-headers",
        "Authorization: YOUR_TOKEN", // 去掉多余的引号
        hls,
    }
}

额外排查建议

  • 确保 YOUR_TOKEN 是有效的授权令牌,可以手动在终端执行ffprobe命令验证:
    ffprobe -v quiet -show_entries format=duration -print_format json -headers "Authorization: YOUR_TOKEN" https://example.com/999/1080/41509578-e299-4594-a506-cf1ff9864a1b.m3u8
    
    如果终端执行也失败,说明令牌或HLS地址有问题,和Go代码无关。
  • 确保ffprobe版本是最新的,旧版本可能对某些HLS格式支持不好。

内容的提问来源于stack exchange,提问作者Nurmuhammet Täjimyradow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:13:18