我是靠谱客的博主 名字长了才好记,这篇文章主要介绍Golang实现Bilibili视频上传压缩保存功能,现在分享给大家,希望可以做个参考。

这个实现包括HTTP服务器处理上传、视频压缩和文件存储功能。

主要功能

  1. 接收视频文件上传
  2. 对视频进行压缩处理
  3. 保存原始视频和压缩后的视频
  4. 提供简单的API接口

代码实现

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"github.com/gin-gonic/gin"
)

const (
	uploadDir    = "./uploads"
	compressedDir = "./compressed"
	maxUploadSize = 1024 * 1024 * 1024 // 1GB
)

func init() {
	// 创建必要的目录
	if err := os.MkdirAll(uploadDir, 0755); err != nil {
		log.Fatal(err)
	}
	if err := os.MkdirAll(compressedDir, 0755); err != nil {
		log.Fatal(err)
	}
}

func main() {
	r := gin.Default()

	// 设置路由
	r.POST("/upload", uploadHandler)
	r.GET("/video/:id", getVideoHandler)

	// 启动服务器
	fmt.Println("Server started on :8080")
	if err := r.Run(":8080"); err != nil {
		log.Fatal(err)
	}
}

// 上传处理函数
func uploadHandler(c *gin.Context) {
	// 限制上传文件大小
	c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxUploadSize)
	if err := c.Request.ParseMultipartForm(maxUploadSize); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "文件太大"})
		return
	}

	// 获取上传的文件
	file, header, err := c.Request.FormFile("video")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的文件"})
		return
	}
	defer file.Close()

	// 检查文件类型
	ext := filepath.Ext(header.Filename)
	if ext != ".mp4" && ext != ".avi" && ext != ".mov" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "不支持的视频格式"})
		return
	}

	// 生成唯一文件名
	timestamp := time.Now().Unix()
	originalFilename := fmt.Sprintf("%d_original%s", timestamp, ext)
	compressedFilename := fmt.Sprintf("%d_compressed.mp4", timestamp)

	// 保存原始文件
	originalPath := filepath.Join(uploadDir, originalFilename)
	outFile, err := os.Create(originalPath)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "无法保存文件"})
		return
	}
	defer outFile.Close()

	if _, err := io.Copy(outFile, file); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "无法保存文件"})
		return
	}

	// 压缩视频
	compressedPath := filepath.Join(compressedDir, compressedFilename)
	if err := compressVideo(originalPath, compressedPath); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "视频压缩失败", "details": err.Error()})
		return
	}

	// 返回响应
	c.JSON(http.StatusOK, gin.H{
		"message":          "视频上传并压缩成功",
		"original_video":   originalFilename,
		"compressed_video": compressedFilename,
		"video_id":         timestamp,
	})
}

// 获取视频处理函数
func getVideoHandler(c *gin.Context) {
	videoID := c.Param("id")
	compressedPath := filepath.Join(compressedDir, videoID+"_compressed.mp4")

	// 检查文件是否存在
	if _, err := os.Stat(compressedPath); os.IsNotExist(err) {
		c.JSON(http.StatusNotFound, gin.H{"error": "视频未找到"})
		return
	}

	// 提供视频文件
	c.File(compressedPath)
}

// 使用FFmpeg压缩视频
func compressVideo(inputPath, outputPath string) error {
	// 检查FFmpeg是否可用
	if _, err := exec.LookPath("ffmpeg"); err != nil {
		return fmt.Errorf("ffmpeg未安装")
	}

	// 设置压缩参数
	cmd := exec.Command(
		"ffmpeg",
		"-i", inputPath,          // 输入文件
		"-c:v", "libx264",        // 视频编码器
		"-crf", "28",            // 压缩质量 (0-51, 越低质量越好)
		"-preset", "fast",       // 编码速度与压缩率的平衡
		"-c:a", "aac",           // 音频编码器
		"-b:a", "128k",          // 音频比特率
		"-movflags", "+faststart", // 优化网络播放
		outputPath,              // 输出文件
	)

	// 运行命令并捕获输出
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("ffmpeg错误: %s, 输出: %s", err, string(output))
	}

	return nil
}

依赖说明

  1. 使用了Gin框架来处理HTTP请求
  2. 需要系统安装FFmpeg来进行视频压缩

安装依赖

go get -u github.com/gin-gonic/gin

安装FFmpeg

  • Ubuntu/Debian: sudo apt-get install ffmpeg
  • macOS: brew install ffmpeg
  • Windows: 从官网下载并添加到PATH

使用说明

  1. 启动服务器: go run main.go
  2. 使用POST请求上传视频到/upload端点表单字段名: video
  3. 使用GET请求访问/video/:id获取压缩后的视频

扩展建议

  1. 添加用户认证
  2. 实现视频元数据存储(如数据库)
  3. 添加更详细的错误处理
  4. 实现进度跟踪
  5. 支持更多视频格式和压缩选项
  6. 添加分布式处理能力
  7. 实现断点续传

这个实现提供了基本功能,可以根据实际需求进行扩展和优化。


最后

以上就是名字长了才好记最近收集整理的关于Golang实现Bilibili视频上传压缩保存功能的全部内容,更多相关Golang实现Bilibili视频上传压缩保存功能内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(108)

评论列表共有 0 条评论

立即
投稿
返回
顶部