闪电龟龟--笔记

万物寻其根,通其堵,便能解其困。
  博客园  :: 新随笔  :: 管理

关于Ffmpeg的使用

Posted on 2022-01-27 12:47  闪电龟龟  阅读(128)  评论(0编辑  收藏  举报

1.资源下载

下载资源路径:http://ffmpeg.org/download.html#build-windows

 

 https://github.com/BtbN/FFmpeg-Builds/releases

 

 下载完成后解压,在bin目录下打开控制台,可检测下载版本或查看帮助

2.工具介绍(具体可以查看https://www.cnblogs.com/fps2tao/p/14234396.html)

  ffmpeg.exe:音视频转码、转换器
  ffplay.exe:简单的音视频播放器
  ffserver.exe:流媒体服务器(这个下载并没有发现)
  ffprobe.exe:简单的多媒体码流分析器

3.单机命令及其参数(具体可以查看https://blog.csdn.net/wangyjfrecky/article/details/81109810)

 3.1音频

 

3.2视频

  1.将视频全部转换为图片

ffmpeg.exe -i testsource/e26d801cea1f4ecab544c3bf8078c6b2.mp4 -r 1 -f image2 testsource/image-%d.jpeg
-i testsource/e26d801cea1f4ecab544c3bf8078c6b2.mp4表示指定资源地址
-r 1表示设置每秒提取一帧
-f image2表示采用的是image2格式
testsource/image-%d.jpeg表示输出地址,%d是顺序数字

  2.设置截取时间和截取张数

ffmpeg.exe -i testsource/e26d801cea1f4ecab544c3bf8078c6b2.mp4 -r 1 -ss 00:00:24 -t 2 -f image2 -s 48x48 testsource/image-%d.jpeg
-ss 00:00:24表示设置起始时间
-t 2表示持续的时间 如果需要使用帧来设置持续时间可以使用 -vframes 2
-s 48x48表示设置输出图片的大小,单位像素
 

 

 

4.C#结合使用按钮

/// <summary>
        /// 根据视频截取封面(封装)
        /// </summary>
        /// <param name="ImagePath">视频路径</param>
        /// <param name="ScrrenTime"></param>
        /// <returns></returns>
        public static string GetScrrenImageFunc(string ImagePath, int ScrrenTime)
        {
            string ReStr = string.Empty;
            try
            {
                if (string.IsNullOrEmpty(ImagePath))
                {
                    return ReStr;
                }
                string ffmpeg = @"bin\ffmpeg.exe";
                ffmpeg = AppDomain.CurrentDomain.BaseDirectory + ffmpeg;
                ProcessStartInfo startInfo = new ProcessStartInfo(ffmpeg);  // 使用进程打开
                startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;  // 隐藏样式窗口
                ReStr = GetImageNameFunc(ImagePath);
                startInfo.Arguments = " -i " + ImagePath + " -r 1 -ss " + GetTimeStrFunc(ScrrenTime) + " -t 1 -s 1725x975 -f image2 " + AppDomain.CurrentDomain.BaseDirectory + ReStr;
                Process TPHandel = new Process();
                TPHandel.StartInfo = startInfo;
                TPHandel.Start();
                TPHandel.WaitForExit(3000);

            }
            catch (Exception err)
            {
                LogHelper.Exception(typeof(LGRES_Resources), "GetScrrenImageFunc", err);
                LogHelper.Exception(typeof(LGRES_Resources), "打印视频路径:"+ ImagePath, new Exception(""));
            }
            return ReStr;
        }
        
        /// <summary>
        /// iis回收清除上次的进程
        /// </summary>
        public static void FfmpegProcessKill()
        {
            foreach(Process TProcess in Process.GetProcesses())
            {
                if (TProcess.ProcessName == "ffmpeg") {
                    TProcess.Kill();
                }
            }
        }

        /// <summary>
        /// 获取图片名称
        /// </summary>
        /// <param name="ImagePath">资源路径</param>
        /// <returns></returns>
        private static string GetImageNameFunc(string ImagePath)
        {
            // 获取指定的名称
            if (ImagePath.IndexOf("/") > -1)
            {
                string[] ImagePathArr = ImagePath.Split('/');
                ImagePath = ImagePathArr[ImagePathArr.Length - 1];
            }
            if (ImagePath.IndexOf(".") > -1)
            {
                string[] ImagePathArr = ImagePath.Split('.');
                ImagePath = ImagePathArr[0];
            }
            // 设置指定的目录
            string FilePath = @"FrameImageUrl";
            if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + FilePath))
            {
                Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + FilePath);
            }
            return FilePath + @"\" + ImagePath + ".jpeg";
        }

        private static Random TRandom = new Random();

        /// <summary>
        /// 转换截取时间
        /// </summary>
        /// <param name="ScrrenTime"></param>
        /// <returns></returns>
        private static string GetTimeStrFunc(int ScrrenTime)
        {
            if (ScrrenTime>=5000)
            {
                ScrrenTime = TRandom.Next(5000, ScrrenTime);
            }
            else
            {
                ScrrenTime = TRandom.Next(0, ScrrenTime);
            }
            string ReStr = string.Empty;
            // 计算时
            if (ScrrenTime >= 1000 * 60 * 60)
            {
                int THours = Convert.ToInt32(Math.Floor(Convert.ToDouble(ScrrenTime) / (1000 * 60 * 60)));
                if (THours > 9)
                {
                    ReStr += THours.ToString() + ":";
                }
                else
                {
                    ReStr += "0" + THours.ToString() + ":";
                }
                ScrrenTime -= THours * 1000 * 60 * 60;
            }
            else
            {
                ReStr += "00:";
            }
            // 计算分
            if (ScrrenTime >= 1000 * 60)
            {
                int THours = Convert.ToInt32(Math.Floor(Convert.ToDouble(ScrrenTime) / (1000 * 60)));
                if (THours > 9)
                {
                    ReStr += THours.ToString() + ":";
                }
                else
                {
                    ReStr += "0" + THours.ToString() + ":";
                }
                ScrrenTime -= THours * 1000 * 60;
            }
            else
            {
                ReStr += "00:";
            }
            // 计算秒
            if (ScrrenTime >= 1000)
            {
                int THours = Convert.ToInt32(Math.Floor(Convert.ToDouble(ScrrenTime) / (1000)));
                if (THours > 9)
                {
                    ReStr += THours.ToString() + ".";
                }
                else
                {
                    ReStr += "0" + THours.ToString() + ".";
                }
                ScrrenTime -= THours * 1000;
            }
            else
            {
                ReStr += "00.";
            }
            // 计算毫秒
            ReStr += ScrrenTime;
            return ReStr;
        }

 Add By 2024-03-22

/**
 * FFmpeg静态帮助类
 命令行 PS D:\下载> .\ffmpeg.exe -i '.\1.mp3' -ac 1 -ar 22050 -b:a 128k -y "2.mp3" *
*/ public class FFmpegHelper { /** * 重新编码处理,资源库规定资源格式: * 音频的采样率/比特率/声道: 128bit/22050hz/单声道 * 返回时长 * */ public static int getResourceFormatConversion(String resourcePathUrl,String targetPathUrl) throws Exception { String ffmpegPathUrl=PublicHelperUtil.getFilePathUrl("ffmpeg.exe"); ffmpegPathUrl = ffmpegPathUrl.replace("file:/", ""); String charSet; ProcessBuilder pb = new ProcessBuilder(); // 设置第三方应用命令 List<String> list = new ArrayList<>(); list.add(ffmpegPathUrl); list.add("-i"); list.add(resourcePathUrl); list.add("-ac"); list.add("1"); // 设置单声道 list.add("-ar"); list.add("22050"); // 设置比特率:22050hz list.add("-b:a"); list.add("128kb"); // 采样率:128bit list.add("-y"); list.add(targetPathUrl); pb.command(list); String os = System.getProperty("os.name"); if (os.toLowerCase().contains("win")) { charSet = "gbk"; } else { charSet = "utf-8"; } // 重定向错误日志信息到 inputstream,很重要,不然错误信息无法抓取到 pb.redirectErrorStream(true); Process process = pb.start(); BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), charSet)); String line = null; int secondNum=0; while ((line = br.readLine()) != null) { line = line.trim(); // Duration: 00:03:52.44, String tempPatterStr="Duration: ([0-9|:|\\.]*?),"; Pattern tempPatter=Pattern.compile(tempPatterStr,Pattern.DOTALL); Matcher tempMatcher=tempPatter.matcher(line); while (tempMatcher.find()){ String tempTimeStrInfo=tempMatcher.group(1); secondNum=strTimeToSecond(tempTimeStrInfo); } //System.out.println(line); } // 等待命令执行完成 int code = process.waitFor(); if (code == 0) { // 通常情况0 表示命令或者脚本正常退出,但是如果脚本自己有返回状态这里需要根据自己状态判断 System.out.println("success"); } else { System.out.println("fail,code=" + code); } return secondNum; } /** * 获取音频时长 * */ public static int getResourcePlayTime(String targetPathUrl) throws Exception { String ffmpegPathUrl=PublicHelperUtil.getFilePathUrl("ffmpeg.exe"); ffmpegPathUrl = ffmpegPathUrl.replace("file:/", ""); String charSet; ProcessBuilder pb = new ProcessBuilder(); // 设置第三方应用命令 List<String> list = new ArrayList<>(); list.add(ffmpegPathUrl); list.add("-i"); list.add(targetPathUrl); pb.command(list); String os = System.getProperty("os.name"); if (os.toLowerCase().contains("win")) { charSet = "gbk"; } else { charSet = "utf-8"; } // 重定向错误日志信息到 inputstream,很重要,不然错误信息无法抓取到 pb.redirectErrorStream(true); Process process = pb.start(); BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), charSet)); String line = null; int secondNum=0; while ((line = br.readLine()) != null) { line = line.trim(); // Duration: 00:03:52.44, String tempPatterStr="Duration: ([0-9|:|\\.]*?),"; Pattern tempPatter=Pattern.compile(tempPatterStr,Pattern.DOTALL); Matcher tempMatcher=tempPatter.matcher(line); while (tempMatcher.find()){ String tempTimeStrInfo=tempMatcher.group(1); secondNum=strTimeToSecond(tempTimeStrInfo); } System.out.println(line); } // 等待命令执行完成 int code = process.waitFor(); if (code == 0) { // 通常情况0 表示命令或者脚本正常退出,但是如果脚本自己有返回状态这里需要根据自己状态判断 System.out.println("success"); } else { System.out.println("fail,code=" + code); } return secondNum; } // 将String(00:03:52.44)转换成long时长 public static int strTimeToSecond(String dataStr) throws Exception { if(StringUtils.isBlank(dataStr)){ return 0; } dataStr=dataStr.split("\\.",-1)[0]; String[] hmsTimeInfos=dataStr.split(":",-1); int backTimeStamp=0; if(hmsTimeInfos.length>0){ backTimeStamp+=Integer.parseInt(hmsTimeInfos[hmsTimeInfos.length-1]); } if(hmsTimeInfos.length>1){ backTimeStamp+=Integer.parseInt(hmsTimeInfos[hmsTimeInfos.length-2])*60; } if(hmsTimeInfos.length>2){ backTimeStamp+=Integer.parseInt(hmsTimeInfos[hmsTimeInfos.length-3])*3600; } return backTimeStamp; } /* * 将秒时长转换为 HH:mm:ss * */ public String secondToStrTime(long secondNum) throws Exception { String[] tempReInfos = new String[3]; if (secondNum >= 3600) { int hourNum = (int) Math.floor((double) secondNum / 3600); if (hourNum > 9) { tempReInfos[0] = String.valueOf(hourNum); } else { tempReInfos[0] = "0" + hourNum; } secondNum -= hourNum * 3600L; } else { tempReInfos[0] = "00"; } if (secondNum >= 60) { int minutesNum = (int) Math.floor(Double.valueOf(secondNum) / 60); if (minutesNum > 9) { tempReInfos[1] = String.valueOf(minutesNum); } else { tempReInfos[1] = "0" + minutesNum; } secondNum -= minutesNum * 60L; } else { tempReInfos[1] = "00"; } if (secondNum > 9) { tempReInfos[2] = String.valueOf(secondNum); } else { tempReInfos[2] = "0" + secondNum; } return String.join(":", tempReInfos); } }

 

End By 2024-03-22

 

 

 

 

待续、、