• .net core Docker 容器添加ffmpeg 获取视频信息和截图


    最近在处理上传视频,需要获取视频信息和截图,这里就需要用到ffmpeg;

    由于我的项目是在docker compose中运行调试,所以ffmpeg也需要在docker中能调用;

    网上找到的方法在Dockerfile中安装ffmpeg;

    .net core 运行的docker容器可以理解为一个安装了.net core runtime的轻量型linux,所以我们要在docker中调用ffmpeg,就需要在这个linux中安装ffmpeg;

    下面是我的Dockerfile 重点是前面的两个RUN 命令,复制这两个RUN 到Dockerfile就可以。(因为我还需要处理Excel所以使用了NPOI,这个linux下也是要安装libgdiplus才能运行;)

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
    
    RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list 
        && apt-get update 
        && apt-get install -y ffmpeg 
        && apt-get clean && apt-get autoclean && apt-get autoremove 
        && rm -rf /var/lib/apt/lists/*
    
    RUN apt-get update && apt-get install -y libgdiplus libc6-dev && ln -s /usr/lib/libgdiplus.so /usr/lib/gdiplus.dll
    WORKDIR /app
    EXPOSE 80
    EXPOSE 443
    
    FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
    WORKDIR /src
    COPY ["test/test.csproj", "test/"]
    RUN dotnet restore "test/test.csproj"
    COPY . .
    WORKDIR "/src/test"
    RUN dotnet build "test.csproj" -c Release -o /app/build
    
    FROM build AS publish
    RUN dotnet publish "test.csproj" -c Release -o /app/publish
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    VOLUME /app/wwwroot
    ENTRYPOINT ["dotnet", "test.dll"]

    然后就可以使用ffmpeg 命令了,我这里适配和window和linux 程序,---- mac还没有试过,请忽略;

    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace test.Ffmpeg
    {
        public static class FfmpegHelper
        {
            private static System.Diagnostics.ProcessStartInfo cmdFfmpeg;
            private static System.Diagnostics.ProcessStartInfo cmdFfprobe;
            static FfmpegHelper()
            {
               
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    string ffmpegPath = "/usr/bin/ffmpeg";
                    string ffprobePath = "/usr/bin/ffprobe";
                    cmdFfmpeg = new System.Diagnostics.ProcessStartInfo(ffmpegPath);
                    cmdFfprobe = new System.Diagnostics.ProcessStartInfo(ffprobePath);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    string ffmpegPath = AppDomain.CurrentDomain.BaseDirectory+ "Ffmpeg\ffmpeg.exe";
                    string ffprobePath = AppDomain.CurrentDomain.BaseDirectory + "Ffmpeg\ffprobe.exe";
                    cmdFfmpeg = new System.Diagnostics.ProcessStartInfo(ffmpegPath);
                    cmdFfprobe = new System.Diagnostics.ProcessStartInfo(ffprobePath);
    
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    string ffmpegPath = "/usr/bin/ffmpeg";
                    string ffprobePath = "/usr/bin/ffprobe";
                    cmdFfmpeg = new System.Diagnostics.ProcessStartInfo(ffmpegPath);
                    cmdFfprobe = new System.Diagnostics.ProcessStartInfo(ffprobePath);
                }
    
                cmdFfmpeg.RedirectStandardError = false; // 输出错误
                cmdFfmpeg.RedirectStandardOutput = true; //输出打印
                cmdFfmpeg.UseShellExecute = false; //使用Shell
                cmdFfmpeg.CreateNoWindow = true;  //创建黑窗
    
    
                cmdFfprobe.RedirectStandardError = false; //set false
                cmdFfprobe.RedirectStandardOutput = true;
                cmdFfprobe.UseShellExecute = false; //set true
                cmdFfprobe.CreateNoWindow = true;  //don't need the black window
            }
    
            /// <summary>
            /// 获取视频信息
            /// </summary>
            /// <param name="path"></param>
            public static async Task<VideoInfoModel> GetVideoInfo(string path)
            {
                try
                {
                    string command = $"-i {path} -print_format json -show_format -show_streams -show_data";
                    cmdFfprobe.Arguments = command;
    
                    System.Diagnostics.Process cmd = new System.Diagnostics.Process();
                    cmd.StartInfo = cmdFfprobe;
                    cmd.Start();
    
                    string InfoStr = await cmd.StandardOutput.ReadToEndAsync();
                    cmd.WaitForExit(10000);
    
                    VideoInfoModel resp = JsonConvert.DeserializeObject<VideoInfoModel>(InfoStr);
                    return resp;
                }
                catch (Exception)
                {
                    return null;
                }
                
            }
            /// <summary>
            /// 视频截图
            /// </summary>
            /// <param name="path"></param>
            /// <param name="outPath"></param>
            public static void VideoScreenshot(string path,string outPath)
            {
                string command = $"-i {path} -y -q:v 7 -f image2 -t 0.001 {outPath}";
                
    
                cmdFfmpeg.Arguments = command;
    
                System.Diagnostics.Process cmd = new System.Diagnostics.Process();
                cmd.StartInfo = cmdFfmpeg;
                cmd.Start();
                cmd.WaitForExit(10000);
    
            }
        }
    }
  • 相关阅读:
    求解整数集合的交集(腾讯笔试)
    关于屏幕适配之比例布局
    (转)注册JNI函数的两种方式
    正则表达式记录
    当年一个简单可用的多线程断点续传类
    最近用到的几个工具方法
    Android中包含List成员变量的Parcel以及Parcel嵌套写法示例
    java实现计算MD5
    一个用于去除状态栏和虚拟导航栏的BaseActivity
    MVP的模板
  • 原文地址:https://www.cnblogs.com/zhanghm1/p/13032207.html
Copyright © 2020-2023  润新知