引言

视频网站内,使用视频下载嗅探器下载了视频,打开资源管理器一看,是几千个.ts文件,见下图:

 

通过播放部分视频,发现其实内容是完整的,只是自动切割了多份,倘若无缝拼接为一个完整视频单元,就可以正常播放观赏了。

经过考虑,

  • 可以使用视频编辑软件,比如PR,导入素材然后重新编排输出,缺点是耗时,而且二次编码损画面质量;
  • 可以考虑使用无损拼接视频的工具,可参考笔者另一篇博文:【视频分割工具】无损快速分割视频软件分享[切分][分P神器]
  • 或者直接使用命令提示符 / 终端,调用FFmpeg等工具。或者不借助任何工具或插件,就用原生的MS-Dos。

相信原生dos可以实现。那么如果素材是文本、图像和音频呢,我们一同尝试一下。


首先

简单尝试copy命令:

copy /b 1.ts+2.ts+3.ts combine.ts

可以得到理想结果,三个片段结合至一个且正常播放。copy命令是cmd中常用的操作文件指令,它可以进行拷贝文件、修改命名、移动文件等,这里使用了合并文件的功能,使用操作符+/b代表二进制式操作。

如果暴力得写下命令如:

copy /b 0.ts+1.ts+2.ts+...+2368.ts combine.ts

咱们是可以理解的,但是dos理解不了。需要详细定义什么是“...”

因此需要把所有的文件清单列出来,即每个文件的文件名加后缀的清单,每个文件名间加“+”。如:

新建一个批处理程序.bat,使用for循环,把字符整理好一并存入一变量里,如下脚本:

set "fileList="   REM 变量 用于存放字符

for /L %%i in (0, 1, 2368) do (
set "fileList=!fileList!%%i.ts+" REM 依次拼接字符
) set "fileList=!fileList:~0,-1!" REM 移除最后一个 +

执行后发现,只有连接到1160.ts。后面的并没有执行:

什么原因呢,最可疑的是变量的缓冲容量限制,存不下那么多字符。最直接的解决方法是可以分批次进行处理:

  1. 第一批次  0.ts+1.ts+2.ts+...+999.ts ,合并为combine1.ts
  2. 第二批次  1000.ts+1001.ts+1002.ts+...+1999.ts ,合并为combine2.ts
  3. 第三批次  2000.ts+2001.ts+2002.ts+...+2348.ts ,合并为combine3.ts
  4. 最后  combine1.ts+combine2.ts+combine3.ts ,  合并为combine.ts
REM @echo off
setlocal enabledelayedexpansion ::--------第一批次---------------
set "outputFile=combine1.ts"
set "fileList=" for /L %%i in (0, 1, 999) do (
set "fileList=!fileList!%%i.ts+"
) set "fileList=!fileList:~0,-1!" REM 移除最后一个+ echo !fileList! > ./fileList.txt REM 方便调试 copy /b !fileList! "%outputFile%" ::----------------------------- pause ::--------第二批次---------------
set "outputFile=combine2.ts"
set "fileList=" for /L %%i in (1000, 1, 1999) do (
set "fileList=!fileList!%%i.ts+"
) set "fileList=!fileList:~0,-1!" REM 移除最后一个+ echo !fileList! > ./fileList.txt copy /b !fileList! "%outputFile%" ::----------------------------- pause ::--------第三批次---------------
set "outputFile=combine3.ts"
set "fileList=" for /L %%i in (1999, 1, 2348) do (
set "fileList=!fileList!%%i.ts+"
) set "fileList=!fileList:~0,-1!" REM 移除最后一个+ echo !fileList! > ./fileList.txt copy /b !fileList! "%outputFile%" ::----------------------------- pause ::--------最后-----------------
copy /b combine1.ts+combine2.ts+combine3.ts combine.ts pause

放在 .ts 文件所在文件夹下,运行脚本,得到最后的视频文件combine.ts。经测验,正常播放,没有问题!


接着

有同学可能要提议,说cmd中最有魅力的莫过于通配符的使用,例如可以使用 *.ts 代指文件夹下所有的ts文件,那么可以这样做【注意,以下是错误结果】:

copy /b *.ts combine.ts

可是经测试,这样操作是可行,但是结果不理想,把所有的文件合并为一个,但是打开之后发现视频全部打乱,无法正常欣赏。因此暴力式合并是不可取的。

如果想要更随心得管理命令,应该将有待合并的文件名导出成数个数据文件,比如.txt,然后读取这些文件的文本,作为copy命令的参数,随后执行!

对了,笔者在引言中说到,对于其他格式的文件也想试试合并操作,那么下面给出几个示例


文本合并

设有四个txt文档,有序合并为一个:

copy /a 1.txt+2.txt+3.txt+4.txt final.txt

或者逐一把每一个文档先读出来放变量中,然后合并:

四个文档对应四个字符串变量   var1  var2   var3   var4   , 最后字符合并,输出给新变量,然后echo > 重定向给.txt保存下来。见代码:

@echo off
setlocal enabledelayedexpansion rem 定义要读取的四个文件
set "file1=1.txt"
set "file2=2.txt"
set "file3=3.txt"
set "file4=4.txt" rem 定义合并后的文件
set "mergedFile=merged.txt" rem 读取第一个文件内容到变量 var1
set "var1="
for /f "usebackq delims=" %%a in ("%file1%") do (
set "var1=!var1!%%a"
set "var1=!var1!"
) rem 读取第二个文件内容到变量 var2
set "var2="
for /f "usebackq delims=" %%a in ("%file2%") do (
set "var2=!var2!%%a"
set "var2=!var2!"
) rem 读取第三个文件内容到变量 var3
set "var3="
for /f "usebackq delims=" %%a in ("%file3%") do (
set "var3=!var3!%%a"
set "var3=!var3!"
) rem 读取第四个文件内容到变量 var4
set "var4="
for /f "usebackq delims=" %%a in ("%file4%") do (
set "var4=!var4!%%a"
set "var4=!var4!"
) rem 合并四个变量的内容
set "mergedContent=!var1!!var2!!var3!!var4!" rem 将合并后的内容写入新文件
echo !mergedContent! > "%mergedFile%" echo 文件合并完成,合并后的文件为 %mergedFile% endlocal

不过这番操作,仅仅是字符操作,并没有换行,因此合成了一行。另外还有type命令也可以实现类似操作。


图像合并

对于图像操作,纯粹靠dos原生系统是几乎不可能的,图像操作需要很复杂的运算,需要其他工具。

可以尝试使用PowerShell,调用程序集,如 System.Drawing

# 添加 System.Drawing 程序集以便使用图像处理类
Add-Type -AssemblyName System.Drawing # 从文件加载第一张图片
$img1 = [System.Drawing.Image]::FromFile("image1.jpg") # 从文件加载第二张图片
$img2 = [System.Drawing.Image]::FromFile("image2.jpg") # 计算新图像的宽度:两张图片的宽度之和
$width = $img1.Width + $img2.Width # 计算新图像的高度:取两张图片中较高的高度
$height = [Math]::Max($img1.Height, $img2.Height) # 创建一个新的位图对象,用于存储合并后的图片
$newImage = New-Object System.Drawing.Bitmap $width, $height # 从新创建的位图中获取图形对象,以便进行绘制
$graphics = [System.Drawing.Graphics]::FromImage($newImage) # 在新图像的 (0, 0) 位置绘制第一张图片
$graphics.DrawImage($img1, 0, 0) # 在新图像的 (img1.Width, 0) 位置绘制第二张图片,确保它紧挨着第一张
$graphics.DrawImage($img2, $img1.Width, 0) # 将合并后的图像保存为一个新的 JPG 文件
$newImage.Save("merged_image.jpg") # 释放图形对象和图像对象的资源
$graphics.Dispose()
$img1.Dispose()
$img2.Dispose()
$newImage.Dispose() # 输出合并完成的提示
Write-Host "合并完成,输出文件为: merged_image.jpg"

这样两张图片便可简单的“粘合在一起”。还有其他细节可以参考笔者另一篇文章:PowerShell开发小工具 · 四张照片拼成一张

如果执意要用dos,可以找图像处理库,比如 ImageMagicK。下面是合并2张图片的示例代码:

@echo off
rem 配置图片地址以及名称,还有要合并的图片文件名
set img1=1.jpg
set img2=2.jpg
set output=merged_image.jpg rem 检查 ImageMagick 是否安装
where magick >nul 2>nul
if errorlevel 1 (
echo ImageMagick 未安装,请先安装 ImageMagick。
exit /b
) rem 合并图片,使用 +append 水平合并
magick "%img1%" "%img2%" +append "%output%" echo 合并完成,输出文件为: %output%
pause

PS: 在安装过程中,确保选中“Install legacy utilities (e.g., convert)”选项,以便使用命令行工具。

以下给一个5张照片水平拼接的例子:

       

上面5张图片,水平合并:

magick 1.jpg 2.jpg 3.jpg 4.jpg 5.jpg +append combine_5.jpg

得:

照片大小都不一致,因此会得到很奇怪的效果。


音频合并

最后还有音频文件的合并尝试。准备3段音频:1.wav   2.wav  3.wav  (不同格式的还是不要自找苦吃了,先转换格式吧)

对于音频文件,cmd不好处理的,还是用FFmpeg吧!不过千万别以为笔者没试过,强制执行copy /b,要么打不开,要么音频播放软件识别错误,即使能播放,时间线也是错乱的!

下面是使用FFmpeg工具集的例子:

rem @echo off
rem 设置要合并的 WAV 文件名
set wav1=1.wav
set wav2=2.wav
set wav3=3.wav
set output=merged_output.wav rem 检查 FFmpeg 是否安装
where ffmpeg >nul 2>nul
if errorlevel 1 (
echo FFmpeg 未安装,请先安装 FFmpeg。
pause
exit /b
) rem 创建一个临时文件,列出要合并的 WAV 文件
(
echo file '%wav1%'
echo file '%wav2%'
echo file '%wav3%'
) > file_list.txt rem 使用 FFmpeg 合并 WAV 文件
ffmpeg -f concat -safe 0 -i file_list.txt -c copy "%output%" rem 删除临时文件
del file_list.txt echo 合并完成,输出文件为: %output%
pause

PS: 使用 ffmpeg 命令进行合并。选项 -f concat 指定格式为拼接,-safe 0 允许使用绝对路径,-c copy 表示直接复制音频流。


结尾

合并文件,如果不是像笔者闲得蛋疼,还是别去使用cmd做,交给专业软件或工具吧。此篇文章也就是试验一下,不过针对学习cmd命令行脚本而言是很有参考价值。

而对于文本而言,其实cmd来合并操作,有时候还有用武之地,以后碰到了再细聊。视频的话,遇到像本文一开始的情景,很多同格式同规格的视频文件,使用copy /b 还挺方便的。

如何调用CMD实现多个同类文件合并的研究 · 二进制 · 依次 · 文本图像视频音频的更多相关文章

  1. C# 调用cmd命令行路径中带空格问题

    今天打包winform程序,程序中本身有一处需要调用cmd.exe,打包安装在C:\Program Files目录下,然后调用cmd的地方,就弹出了C:\Program不是内部或外部命令,也不是可运行 ...

  2. C#程序调用cmd执行命令

    对于C#通过程序来调用cmd命令的操作,网上有很多类似的文章,但很多都不行,竟是漫天的拷贝.我自己测试整理了一下. 代码: string str = Console.ReadLine(); Syste ...

  3. [转]Delphi调用cmd的两种方法

    delphi调用cmd的两种方法vars:string;begins:='cmd.exe /c '+edit1.Text+' >c:\1.txt';winexec(pchar(s),sw_hid ...

  4. C#程序调用cmd执行命令(转)

    C#通过程序来调用cmd命令的操作 string str = Console.ReadLine(); System.Diagnostics.Process p = new System.Diagnos ...

  5. 用C#中实现的,调用CMD来执行BCP的代码

    用C#中实现的,调用CMD来执行BCP的代码 用c#中实现,调用cmd来执行bcp的代码,大家共享!引用空间:using System;using System.Data;using System.D ...

  6. C# 调用CMD执行命令行

    这几天用c#做了一个项目,其中一个功能是要把生成的临时文件隐藏,同时,不能在屏幕上有调用CMD的痕迹,这里生成的临时文件的绝对路径为delfile为文件的绝对路径, 代码如下: private voi ...

  7. JAVA:调用cmd指令(支持多次手工输入)

    JDK开发环境:1.8 package com.le.tool; import java.io.BufferedReader; import java.io.File; import java.io. ...

  8. 使用node自动生成html并调用cmd命令提交代码到仓库

    生成html提交到git仓库 基于目前的express博客,写了一点代码,通过request模块来请求站点,将html保存到coding-pages目录,复制静态文件夹到coding-pages,最后 ...

  9. ASP.NET调用cmd命令提示符拒绝访问解决方案

    using System.Diagnostics; public class CmdHelper { private static string CmdPath = @"C:\Windows ...

  10. Sublime Text 3 调用cmd运行c、java、python、batch file

    一.调用cmd运行c(首先复制MinGW到C盘根目录,并添加环境变量) Tools --> Build System --> New Build System 删除所有内容 复制如下代码进 ...

随机推荐

  1. Qt开发经验小技巧181-185

    Qt天生就是linux的,从linux开始发展起来的,所以不少Qt程序员经常的开发环境是linux,比如常用的ubuntu等系统,整理了一点常用的linux命令. 命令 功能 sudo -s 切换到管 ...

  2. SHA256 64 位加密

    /// <summary> /// SHA256 64位加密 /// </summary> /// <param name="input">&l ...

  3. 高通Android工程释放ADSP侧GPIO给AP侧(HLOS)解决uart只能收或者发,gpio 无法配置成输入或者输出

    在许多sensor的调试过程中总是会遇到各种GPIO被占用的情况,特别是以下几种情况:UART 只能发或收,GPIO 配置了pinctl output但是gpio依旧为输入. 1.判断GPIO口状态 ...

  4. Netty的实现原理、特点与优势、以及适用场景

    Netty 1.介绍 Netty是由JBOSS提供的一个java开源框架. Netty是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.UDP和文件传输的支持.作为当前最流行的NIO框架,Ne ...

  5. Docker与联合文件系统

    1. 联合文件系统 概念 UnionFS(联合文件系统)是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次次的提交来一层一层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(u ...

  6. ctfshow--web4 include日志注入

    这题和第三题有点不一样,这题的把php 和 data 都过滤掉了 一旦我们输入这个关键字就页面就会报error 一开始是没啥头绪的,后面上网查了一下,可以通过日志记录来注入代码 对于Apache,日志 ...

  7. ORACLE存储过程编程应用实例-门诊药房发药

    最近两个整理了门诊药房发药的业务逻辑,准备通过存储过程实现数据处理.耗费两天时间验证终于完成,对存储过程的了解又深入了一些,总结如下: 1.游标的遍历使用了FOR IN语句进行循环,比FETCH与方便 ...

  8. 部署Palworld幻兽帕鲁服务器最佳实践(Ubuntu)

    本文为您介绍Ubuntu系统部署Palworld幻兽帕鲁服务器的最/佳实践. 1.登录云主机控制台,选择创建云主机的资源池,点击"创建云主机"按钮. 2.基础配置. CPU架构选择 ...

  9. 云电脑:IO虚拟化实现的技术分析

    本文分享自天翼云开发者社区<云电脑:IO虚拟化实现的技术分析>,作者:大利 云电脑是一种基于云计算技术的虚拟化电脑,它通过网络将物理硬件资源虚拟化成多个虚拟机,每个虚拟机都拥有独立的操作系 ...

  10. Pyinstaller打包工具

    本篇博客主要介绍的是pyinstaller在windows下的基本使用和基础避坑 在windows中使用pyinstaller工具打包时会出现一个问题,在打包列表会看到这样的警告信息: django. ...