这个实现包括HTTP服务器处理上传、视频压缩和文件存储功能。
主要功能
- 接收视频文件上传
- 对视频进行压缩处理
- 保存原始视频和压缩后的视频
- 提供简单的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
}
依赖说明
- 使用了Gin框架来处理HTTP请求
- 需要系统安装FFmpeg来进行视频压缩
安装依赖
go get -u github.com/gin-gonic/gin
安装FFmpeg
- Ubuntu/Debian: sudo apt-get install ffmpeg
- macOS: brew install ffmpeg
- Windows: 从官网下载并添加到PATH
使用说明
- 启动服务器: go run main.go
- 使用POST请求上传视频到/upload端点表单字段名: video
- 使用GET请求访问/video/:id获取压缩后的视频
扩展建议
- 添加用户认证
- 实现视频元数据存储(如数据库)
- 添加更详细的错误处理
- 实现进度跟踪
- 支持更多视频格式和压缩选项
- 添加分布式处理能力
- 实现断点续传
这个实现提供了基本功能,可以根据实际需求进行扩展和优化。
最后
以上就是名字长了才好记最近收集整理的关于Golang实现Bilibili视频上传压缩保存功能的全部内容,更多相关Golang实现Bilibili视频上传压缩保存功能内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复