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
}
相关推荐
GDAL1 天前
go.mod 文件讲解
golang·go.mod
Java面试题总结1 天前
Go图像处理基础: image包深度指南
图像处理·算法·golang
EasyDSS1 天前
RTMP高清推流直播/视频转码EasyDSS在无人机RTMP直播场景中的应用技术解析
ffmpeg·音视频·无人机·视频转码·语音转写·点播技术
EasyGBS1 天前
场景化落地指南:国标GB28181视频分析EasyGBS视频质量诊断在5大行业的实战应用
音视频·国标gb28181·视频质量诊断·花屏检测
码农xo1 天前
android 设备实时传输相机采集的视频到电脑pc端 通过内网wifi 方案
android·数码相机·音视频
2502_911679141 天前
产线音频测试的性价比之选:APx515B音频分析仪深度解读
音视频
qq_316837751 天前
华为obs 私有桶 音频 使用uniapp 安卓端播放-99的问题
uni-app·音视频
robch1 天前
golang container/heap 是一个为任意类型实现堆(优先队列)接口的包
数据结构·算法·golang
leonkay2 天前
Golang语言闭包完全指南
开发语言·数据结构·后端·算法·架构·golang
echome8882 天前
Go 语言并发编程实战:用 Goroutine 和 Channel 构建高性能任务调度器
开发语言·后端·golang