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
}
相关推荐
五岁小孩4 小时前
Go 原理之 GMP 并发调度模型
golang·gmp·并发调度模型
Hello.Reader16 小时前
Go-Elasticsearch v9 安装与版本兼容性
elasticsearch·golang·jenkins
五岁小孩17 小时前
实操使用 go pprof 对生产环境进行性能分析(问题定位及代码优化)
性能优化·golang·pprof
源码_V_saaskw17 小时前
JAVA图文短视频交友+自营商城系统源码支持小程序+Android+IOS+H5
java·微信小程序·小程序·uni-app·音视频·交友
一杯科技拿铁1 天前
Go 的时间包:理解单调时间与挂钟时间
开发语言·后端·golang
线程A1 天前
Go 语言函数设计原则:避免修改传入参数
golang
猫头虎1 天前
2025年02月11日 Go生态洞察:Go 1.24 发布亮点全面剖析
开发语言·后端·python·golang·go·beego·go1.19
肥or胖1 天前
【音视频协议篇】WebRTC 快速入门
ffmpeg·音视频·webrtc
aqi001 天前
FFmpeg开发笔记(七十八)采用Kotlin+Compose的NextPlayer播放器
android·ffmpeg·音视频·直播·流媒体
Python涛哥1 天前
go语言基础教程:【2】基础语法:基本数据类型(整形和浮点型)
android·开发语言·golang