# All files / services ffmpeg-example.ts

0% Statements 0/82
0% Branches 0/1
0% Functions 0/1
0% Lines 0/82

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199

     /**
     * FFmpeg 处理器使用示例
     * 演示如何在 OSS 模式下处理音频/视频
     */

    import { FFmpegProcessor } from './ffmpeg.processor';

    // ==================== 示例 1: 合并多个音频（OSS URL） ====================
    async function mergeAudioFromOSS() {
      // OSS 音频 URL 数组
      const audioUrls = [
        'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/part1.mp3',
        'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/part2.mp3',
        'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/part3.mp3',
      ];

      // 自动下载、合并、上传
      const mergedUrl = await FFmpegProcessor.mergeAudio(audioUrls, 'mp3');
      console.log('合并后的音频:', mergedUrl);
      // 输出: https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/xxx/merged.mp3
    }

    // ==================== 示例 2: 混合音频和视频 ====================
    async function mergeAudioVideo() {
      const audioUrl = 'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/narration.mp3';
      const videoUrl = 'https://bucket.oss-cn-hangzhou.aliyuncs.com/video/456/visual.mp4';
      const bgmUrl = 'https://bucket.oss-cn-hangzhou.aliyuncs.com/material/bgm.mp3';

      // 合并音频、视频和背景音乐
      const finalUrl = await FFmpegProcessor.mergeAudioVideo(
        audioUrl,
        videoUrl,
        bgmUrl,
        0.3 // 背景音乐音量 30%
      );
      console.log('最终视频:', finalUrl);
    }

    // ==================== 示例 3: 获取音频时长 ====================
    async function getAudioDuration() {
      const audioUrl = 'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/audio.mp3';

      // 自动下载、获取时长、清理临时文件
      const duration = await FFmpegProcessor.getDuration(audioUrl);
      console.log(`音频时长: ${duration}秒`);
    }

    // ==================== 示例 4: 转换音频格式 ====================
    async function convertAudioFormat() {
      const wavUrl = 'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/audio.wav';

      // WAV 转 MP3
      const mp3Url = await FFmpegProcessor.convertFormat(wavUrl, 'mp3', '192k');
      console.log('MP3 文件:', mp3Url);

      // MP3 转 AAC
      const aacUrl = await FFmpegProcessor.convertFormat(mp3Url, 'aac', '128k');
      console.log('AAC 文件:', aacUrl);
    }

    // ==================== 示例 5: 裁剪音频 ====================
    async function trimAudio() {
      const audioUrl = 'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/full.mp3';

      // 从 10 秒开始，裁剪 30 秒
      const trimmedUrl = await FFmpegProcessor.trimAudio(audioUrl, 10, 30);
      console.log('裁剪后的音频:', trimmedUrl);
    }

    // ==================== 示例 6: 调整音量 ====================
    async function adjustVolume() {
      const audioUrl = 'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/audio.mp3';

      // 音量加倍
      const louderUrl = await FFmpegProcessor.adjustVolume(audioUrl, 2.0);
      console.log('音量加倍:', louderUrl);

      // 音量减半
      const quieterUrl = await FFmpegProcessor.adjustVolume(audioUrl, 0.5);
      console.log('音量减半:', quieterUrl);
    }

    // ==================== 示例 7: 混合使用本地和 OSS 文件 ====================
    async function mixLocalAndOSS() {
      // 混合本地文件和 OSS URL
      const mixedUrls = [
        './uploads/audio/123/local.mp3',           // 本地文件
        '/uploads/audio/456/another.mp3',          // 本地文件
        'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/789/remote.mp3', // OSS
      ];

      // FFmpegProcessor 会自动处理
      const mergedUrl = await FFmpegProcessor.mergeAudio(mixedUrls, 'mp3');
      console.log('合并结果:', mergedUrl);
    }

    // ==================== 示例 8: 在 TTS 服务中使用 ====================
    // 在 tts.service.ts 中的使用示例
    async function ttsServiceExample() {
      const segmentFiles = [
        'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/segment_0.mp3',
        'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/segment_1.mp3',
        'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/segment_2.mp3',
      ];

      // 合并所有分段
      const finalAudioUrl = await FFmpegProcessor.mergeAudio(segmentFiles, 'mp3');

      // 获取时长
      const duration = await FFmpegProcessor.getDuration(finalAudioUrl);

      console.log('最终音频:', finalAudioUrl);
      console.log('时长:', duration, '秒');

      return {
        audioUrl: finalAudioUrl,
        duration,
      };
    }

    // ==================== 示例 9: 视频生成中使用 ====================
    // 在 video-generator 中的使用示例
    async function videoGeneratorExample() {
      const chapter = {
        audioUrl: 'https://bucket.oss-cn-hangzhou.aliyuncs.com/audio/123/audio.mp3',
        videoUrl: 'https://bucket.oss-cn-hangzhou.aliyuncs.com/video/456/visual.mp4',
      };

      // 合并音频和视频
      const finalVideoUrl = await FFmpegProcessor.mergeAudioVideo(
        chapter.audioUrl,
        chapter.videoUrl
      );

      console.log('最终视频:', finalVideoUrl);
      return finalVideoUrl;
    }

    // ==================== 处理流程说明 ====================
    /*
    使用 OSS 时的 FFmpeg 处理流程：

    1. 检测输入 URL 类型
       - 本地路径（/uploads/ 或 ./） -> 直接使用
       - 远程 URL（http/https） -> 下载到临时目录

    2. 执行 FFmpeg 处理
       - 合并音频
       - 合并音视频
       - 格式转换
       - 裁剪/调整音量
       - 等等...

    3. 上传结果到 OSS
       - 使用 storageService.uploadAudio() 或 uploadVideo()
       - 自动根据 STORAGE_TYPE 选择存储方式

    4. 清理临时文件
       - 自动删除下载的临时文件
       - 自动删除处理后的临时文件

    注意：
    - 所有临时文件保存在 server/temp/ 目录
    - 处理完成后自动清理
    - 支持失败时的异常清理（finally 块）
    */

    // ==================== 性能优化建议 ====================
    /*
    1. 并发下载
       - 多个文件可以并发下载
       - 使用 Promise.all() 加速

    2. 临时文件管理
       - 定期清理 temp 目录
       - 使用 cron 任务定时清理

    3. 超时设置
       - 下载超时: 60秒
       - 合并超时: 5-10分钟
       - 根据实际情况调整

    4. 错误处理
       - 捕获异常并清理临时文件
       - 记录详细日志便于调试
    */

    export {
      mergeAudioFromOSS,
      mergeAudioVideo,
      getAudioDuration,
      convertAudioFormat,
      trimAudio,
      adjustVolume,
      mixLocalAndOSS,
      ttsServiceExample,
      videoGeneratorExample,
    };