Files
huobao-drama/application/services/audio_extraction_service.go
Connor d39759926e 1、添加中英文版本
2、修复已知BUG
3、完善功能
4、添加minimax视频渠道
2026-01-18 05:21:34 +08:00

98 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package services
import (
"fmt"
"path/filepath"
"time"
"github.com/drama-generator/backend/infrastructure/external/ffmpeg"
"github.com/drama-generator/backend/pkg/logger"
)
type AudioExtractionService struct {
ffmpeg *ffmpeg.FFmpeg
log *logger.Logger
}
func NewAudioExtractionService(log *logger.Logger) *AudioExtractionService {
return &AudioExtractionService{
ffmpeg: ffmpeg.NewFFmpeg(log),
log: log,
}
}
type ExtractAudioRequest struct {
VideoURL string `json:"video_url" binding:"required"`
}
type ExtractAudioResponse struct {
AudioURL string `json:"audio_url"`
Duration float64 `json:"duration"`
}
// ExtractAudio 从视频URL提取音频并返回音频文件URL
func (s *AudioExtractionService) ExtractAudio(videoURL string, dataDir string) (*ExtractAudioResponse, error) {
s.log.Infow("Starting audio extraction", "video_url", videoURL)
// 生成输出文件名
timestamp := time.Now().Unix()
audioFileName := fmt.Sprintf("audio_%d.aac", timestamp)
audioOutputPath := filepath.Join(dataDir, "audios", audioFileName)
// 提取音频
extractedPath, err := s.ffmpeg.ExtractAudio(videoURL, audioOutputPath)
if err != nil {
s.log.Errorw("Failed to extract audio", "error", err, "video_url", videoURL)
return nil, fmt.Errorf("failed to extract audio: %w", err)
}
// 获取音频时长(使用提取后的本地文件路径)
duration, err := s.ffmpeg.GetVideoDuration(extractedPath)
if err != nil {
s.log.Errorw("Failed to get audio duration", "error", err, "path", extractedPath)
return nil, fmt.Errorf("failed to get audio duration: %w", err)
}
if duration <= 0 {
s.log.Errorw("Invalid audio duration", "duration", duration, "path", extractedPath)
return nil, fmt.Errorf("invalid audio duration: %.2f", duration)
}
// 构建音频URL相对于data目录
audioURL := fmt.Sprintf("/data/audios/%s", audioFileName)
s.log.Infow("Audio extraction completed",
"video_url", videoURL,
"audio_url", audioURL,
"duration", duration,
"local_path", extractedPath)
return &ExtractAudioResponse{
AudioURL: audioURL,
Duration: duration,
}, nil
}
// BatchExtractAudio 批量提取音频
func (s *AudioExtractionService) BatchExtractAudio(videoURLs []string, dataDir string) ([]*ExtractAudioResponse, error) {
s.log.Infow("Starting batch audio extraction", "count", len(videoURLs))
results := make([]*ExtractAudioResponse, 0, len(videoURLs))
for i, videoURL := range videoURLs {
s.log.Infow("Extracting audio", "index", i+1, "total", len(videoURLs), "video_url", videoURL)
result, err := s.ExtractAudio(videoURL, dataDir)
if err != nil {
s.log.Errorw("Failed to extract audio in batch", "index", i, "video_url", videoURL, "error", err)
// 继续处理其他视频,但记录错误
return nil, fmt.Errorf("failed to extract audio at index %d: %w", i, err)
}
results = append(results, result)
}
s.log.Infow("Batch audio extraction completed", "successful_count", len(results))
return results, nil
}