GO语言实现视频分割

视频分割

每隔10秒分割一次,去掉分割视频的最后0.5秒,合并后删除分割视频

go 复制代码
package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "os"
    "os/exec"
    "path/filepath"
    "strconv"
    "strings"
)

func main() {
    videoPath := "C:\\move\\video.mp4" // 视频文件路径
    outputDir := "C:\\move\\output\\"  // 分割后的视频保存目录
    segmentDuration := 10              // 每个片段的时长(秒)

    // 创建保存目录
    err := os.MkdirAll(outputDir, 0755)
    if err != nil {
        log.Fatal(err)
    }

    // 使用FFprobe获取视频时长
    duration, err := getVideoDuration(videoPath)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("视频时长:", duration)

    // 分割视频
    segments := []string{}
    for i := 0; i < duration; i += segmentDuration {
        outputPath := filepath.Join(outputDir, fmt.Sprintf("segment_%d.mp4", i))
        err := splitVideoSegment(videoPath, outputPath, i, segmentDuration)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("已分割片段: %s\n", outputPath)
        segments = append(segments, outputPath)
    }

    // 合并视频
    outputPath := filepath.Join(outputDir, "merged.mp4")
    err = mergeVideos(segments, outputPath)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("已合并视频: %s\n", outputPath)

    // 删除分割视频
    err = deleteSegmentFiles(segments)
    if err != nil {
        log.Fatal(err)
    }

}

// 使用FFprobe获取视频时长
func getVideoDuration(videoPath string) (int, error) {
    cmd := exec.Command("ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", videoPath)
    output, err := cmd.Output()
    if err != nil {
        return 0, err
    }

    durationFloat, err := strconv.ParseFloat(strings.TrimSpace(string(output)), 64)
    if err != nil {
        return 0, err
    }

    duration := int(durationFloat)
    return duration, nil
}

// 使用FFmpeg分割视频片段并去掉最后0.5秒
func splitVideoSegment(videoPath string, outputPath string, startTime int, duration int) error {
    startTimeStr := strconv.Itoa(startTime)
    durationStr := strconv.FormatFloat(float64(duration)-0.5, 'f', 1, 64) // 减去0.1秒

    cmd := exec.Command("ffmpeg", "-ss", startTimeStr, "-i", videoPath, "-t", durationStr, "-c", "copy", outputPath)
    err := cmd.Run()
    if err != nil {
        return err
    }

    return nil
}

// 合并视频
func mergeVideos(segments []string, outputPath string) error {
    // 创建临时文件用于存储合并的视频文件列表
    tempFile, err := ioutil.TempFile("", "video_segments.txt")
    if err != nil {
        return err
    }
    defer os.Remove(tempFile.Name())

    // 写入视频文件路径到临时文件
    for _, segment := range segments {
        _, err := tempFile.WriteString(fmt.Sprintf("file '%s'\n", segment))
        if err != nil {
            return err
        }
    }

    // 关闭临时文件
    err = tempFile.Close()
    if err != nil {
        return err
    }

    // 执行 concat 操作合并视频
    cmd := exec.Command("ffmpeg", "-f", "concat", "-safe", "0", "-i", tempFile.Name(), "-c", "copy", outputPath)
    err = cmd.Run()
    if err != nil {
        return err
    }

    return nil
}

// 删除分割视频
func deleteSegmentFiles(segments []string) error {
    for _, segment := range segments {
        err := os.Remove(segment)
        if err != nil {
            return err
        }
        fmt.Printf("已删除分割视频: %s\n", segment)
    }
    return nil
}
相关推荐
向阳花开_miemie12 小时前
Android音频学习(十七)——音频数据流转
学习·音视频
小周不长肉12 小时前
视频串行解串器(SerDes)介绍
音视频
bst@微胖子12 小时前
WGAI项目图像视频语音识别功能
人工智能·语音识别·xcode
懒人村杂货铺13 小时前
[特殊字符] 跨端视频通话实战:腾讯云 TRTC + IM(React Native & Web)
react native·音视频·腾讯云
GM_82817 小时前
【Go项目基建】GORM框架实现SQL校验拦截器(完整源码+详解)
sql·golang·拦截器·gorm·慢查询·持久层基建
昨日之日200619 小时前
Wan2.2-S2V - 音频驱动图像生成电影级质量的数字人视频 ComfyUI工作流 支持50系显卡 一键整合包下载
人工智能·音视频
YGGP1 天前
3D 版接雨水
golang
hnxaoli1 天前
win10(三)视频剪裁
音视频
ai产品老杨1 天前
驱动物流创新与协同,助力物流行业可持续发展的智慧物流开源了
人工智能·开源·音视频·能源
xingxing_F1 天前
SoundSource for Mac 音频控制工具
macos·音视频