You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Media Service退役后,能否用Azure Function将AVI转MP4?

AVI转MP4编码解决方案(Azure Function替代Azure Media Service)

针对你遇到的JAVE2/FFmpeg依赖本地文件、无法直接处理Blob输入流的问题,结合输入文件最大100MB的限制,可通过临时文件中转的方式解决,以下是具体实现方案:


方案一:使用JAVE2实现编码

JAVE2确实依赖java.io.File作为输入输出载体,我们可以先将Blob中的AVI文件写入本地临时文件,编码完成后再将输出的MP4文件上传回Blob存储。

核心步骤

  1. 从Blob获取输入流,写入临时文件
  2. 用JAVE2对临时AVI文件进行编码,输出为临时MP4文件
  3. 将临时MP4文件转为输入流,上传至目标Blob容器
  4. 清理临时文件,避免占用资源

代码示例

import com.azure.storage.blob.BlobClient;
import ws.schild.jave.Encoder;
import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;
import ws.schild.jave.encode.VideoAttributes;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class AviToMp4Converter {

    public void convertAviToMp4(BlobClient sourceBlobClient, BlobClient targetBlobClient) throws IOException, EncoderException {
        // 创建临时AVI文件
        Path tempAviPath = Files.createTempFile("temp-", ".avi");
        File tempAviFile = tempAviPath.toFile();
        
        // 将Blob输入流写入临时文件
        try (InputStream blobInputStream = sourceBlobClient.openInputStream()) {
            Files.copy(blobInputStream, tempAviPath, StandardCopyOption.REPLACE_EXISTING);
        }

        try {
            // 创建临时MP4输出文件
            Path tempMp4Path = Files.createTempFile("output-", ".mp4");
            File tempMp4File = tempMp4Path.toFile();

            // 配置JAVE2编码参数
            AudioAttributes audio = new AudioAttributes();
            audio.setCodec("aac");
            audio.setBitRate(128000);
            audio.setChannels(2);
            audio.setSamplingRate(44100);

            VideoAttributes video = new VideoAttributes();
            video.setCodec("h264");
            video.setBitRate(2000000);
            video.setFrameRate(25);

            EncodingAttributes attrs = new EncodingAttributes();
            attrs.setOutputFormat("mp4");
            attrs.setAudioAttributes(audio);
            attrs.setVideoAttributes(video);

            // 执行编码操作
            Encoder encoder = new Encoder();
            encoder.encode(new MultimediaObject(tempAviFile), tempMp4File, attrs);

            // 将MP4文件上传至Blob
            try (InputStream mp4InputStream = new FileInputStream(tempMp4File)) {
                targetBlobClient.upload(mp4InputStream, tempMp4File.length());
            } finally {
                // 清理临时MP4文件
                Files.deleteIfExists(tempMp4Path);
            }
        } finally {
            // 清理临时AVI文件
            Files.deleteIfExists(tempAviPath);
        }
    }
}

方案二:使用FFmpeg实现编码

如果JAVE2的封装无法满足需求,直接调用FFmpeg进程会更灵活,同样通过临时文件中转实现:

核心步骤

  1. 下载Blob中的AVI到临时文件
  2. 调用FFmpeg进程将AVI转码为MP4临时文件
  3. 上传MP4临时文件至Blob
  4. 清理临时文件

代码示例

import com.azure.storage.blob.BlobClient;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class FfmpegConverter {

    public void convertWithFfmpeg(BlobClient sourceBlobClient, BlobClient targetBlobClient) throws IOException, InterruptedException {
        // 创建临时AVI文件
        Path tempAviPath = Files.createTempFile("temp-", ".avi");
        File tempAviFile = tempAviPath.toFile();
        
        // 将Blob内容写入临时文件
        try (InputStream blobInputStream = sourceBlobClient.openInputStream()) {
            Files.copy(blobInputStream, tempAviPath, StandardCopyOption.REPLACE_EXISTING);
        }

        try {
            // 创建临时MP4输出文件
            Path tempMp4Path = Files.createTempFile("output-", ".mp4");
            File tempMp4File = tempMp4Path.toFile();

            // 构建FFmpeg转码命令(需确保Azure Function环境已安装FFmpeg)
            String ffmpegCmd = String.format(
                "ffmpeg -i %s -c:v libx264 -c:a aac -b:a 128k %s",
                tempAviFile.getAbsolutePath(),
                tempMp4File.getAbsolutePath()
            );

            // 执行FFmpeg进程
            Process process = new ProcessBuilder("bash", "-c", ffmpegCmd).start();
            int exitCode = process.waitFor();
            if (exitCode != 0) {
                throw new RuntimeException("FFmpeg转码失败,退出码:" + exitCode);
            }

            // 上传MP4文件至Blob
            try (InputStream mp4InputStream = new FileInputStream(tempMp4File)) {
                targetBlobClient.upload(mp4InputStream, tempMp4File.length());
            } finally {
                Files.deleteIfExists(tempMp4Path);
            }
        } finally {
            Files.deleteIfExists(tempAviPath);
        }
    }
}

注意事项

  • Azure Function环境需预先安装FFmpeg:Linux环境可通过自定义Docker镜像或启动脚本安装;Windows环境需将FFmpeg二进制文件打包进函数部署包。
  • 临时文件存储:Azure Function提供的临时目录(/tmp或%TEMP%)足够容纳100MB的文件,无需担心空间问题。

内容的提问来源于stack exchange,提问作者Sandy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:22:42