胡斌

merge the audio file and video file according to the recordinfo

  1 +
  2 +Microsoft Visual Studio Solution File, Format Version 12.00
  3 +# Visual Studio 2013
  4 +VisualStudioVersion = 12.0.31101.0
  5 +MinimumVisualStudioVersion = 10.0.40219.1
  6 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "merge_av", "merge_av\merge_av.vcxproj", "{F607DD90-3E62-40BA-BF8A-185E597D646D}"
  7 +EndProject
  8 +Global
  9 + GlobalSection(SolutionConfigurationPlatforms) = preSolution
  10 + Debug|Win32 = Debug|Win32
  11 + Release|Win32 = Release|Win32
  12 + EndGlobalSection
  13 + GlobalSection(ProjectConfigurationPlatforms) = postSolution
  14 + {F607DD90-3E62-40BA-BF8A-185E597D646D}.Debug|Win32.ActiveCfg = Debug|Win32
  15 + {F607DD90-3E62-40BA-BF8A-185E597D646D}.Debug|Win32.Build.0 = Debug|Win32
  16 + {F607DD90-3E62-40BA-BF8A-185E597D646D}.Release|Win32.ActiveCfg = Release|Win32
  17 + {F607DD90-3E62-40BA-BF8A-185E597D646D}.Release|Win32.Build.0 = Release|Win32
  18 + EndGlobalSection
  19 + GlobalSection(SolutionProperties) = preSolution
  20 + HideSolutionNode = FALSE
  21 + EndGlobalSection
  22 +EndGlobal
  1 +========================================================================
  2 + 控制台应用程序:merge_av 项目概述
  3 +========================================================================
  4 +
  5 +应用程序向导已为您创建了此 merge_av 应用程序。
  6 +
  7 +本文件概要介绍组成 merge_av 应用程序的每个文件的内容。
  8 +
  9 +
  10 +merge_av.vcxproj
  11 + 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
  12 +
  13 +merge_av.vcxproj.filters
  14 + 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
  15 +
  16 +merge_av.cpp
  17 + 这是主应用程序源文件。
  18 +
  19 +/////////////////////////////////////////////////////////////////////////////
  20 +其他标准文件:
  21 +
  22 +StdAfx.h, StdAfx.cpp
  23 + 这些文件用于生成名为 merge_av.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
  24 +
  25 +/////////////////////////////////////////////////////////////////////////////
  26 +其他注释:
  27 +
  28 +应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。
  29 +
  30 +/////////////////////////////////////////////////////////////////////////////
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <string>
  4 +#include <iostream>
  5 +#include <fstream>
  6 +#include <vector>
  7 +
  8 +bool only_print = false;
  9 +using namespace std;
  10 +
  11 +class fileinfo {
  12 +public:
  13 + float start_time;
  14 + float end_time;
  15 + string start_time_str;
  16 + string end_time_str;
  17 + string name;
  18 +};
  19 +
  20 +enum media_type{
  21 + type_audio = 0,
  22 + type_video = 1,
  23 +};
  24 +vector<fileinfo> media_files[2];
  25 +
  26 +void run_shell_cmd(char * cmd)
  27 +{
  28 + if (only_print){
  29 + printf("\n%s", cmd);
  30 + }
  31 + else {
  32 + system(cmd);
  33 + }
  34 +}
  35 +
  36 +char * default_vcodec_param = " -vcodec libx264 -level 3.1 -preset veryfast -g 40 -r 20 ";
  37 +char * default_acodec_param = " -acodec copy ";
  38 +char vcodec_param[1024];
  39 +char acodec_param[1024];
  40 +
  41 +void addinfo( string t, string name, bool bstart ){
  42 + media_type mtype = name.substr(name.length() - 4, name.length()) == ".aac" ? type_audio : type_video;
  43 + if (bstart) {
  44 + fileinfo f;
  45 + f.start_time = atof(t.c_str());
  46 + f.end_time = f.start_time;
  47 + f.start_time_str = t;
  48 + f.end_time_str = t;
  49 + f.name = name;
  50 +
  51 + media_files[mtype].push_back(f);
  52 + }
  53 + else {
  54 + vector<fileinfo> & files = media_files[mtype];
  55 + int i;
  56 + for (i = 0; i < files.size(); i++) {
  57 + if (files[i].name == name) {
  58 + files[i].end_time = atof(t.c_str());
  59 + files[i].end_time_str = t;
  60 + break;
  61 + }
  62 + }
  63 +
  64 + if (i == files.size())
  65 + {
  66 + cout << "\nerror ,file : " << name << " close but not started!";
  67 + }
  68 + }
  69 +}
  70 +
  71 +void split(string str, string separator, vector<string> &result, bool includeEmptyItem = false) {
  72 + result.clear();
  73 + string::size_type position = str.find(separator);
  74 + string::size_type lastPosition = 0;
  75 + int separatorLength = separator.length();
  76 +
  77 + while (position != str.npos) {
  78 + string s = str.substr(lastPosition, position - lastPosition);
  79 + if (!s.empty() || includeEmptyItem)
  80 + result.push_back(s);
  81 + lastPosition = position + separatorLength;
  82 + position = str.find(separator, lastPosition);
  83 + }
  84 + result.push_back(str.substr(lastPosition, string::npos));
  85 +}
  86 +
  87 +void split_audio(fileinfo audio, float audio_start, float duration, int nf)
  88 +{
  89 + char buf[2048];
  90 + sprintf(buf, "ffmpeg -y -i %s -ss %.3f -t %.3f %s %d_%s", audio.name.c_str(), audio_start, duration, acodec_param, nf, audio.name.c_str());
  91 + run_shell_cmd(buf);
  92 +}
  93 +
  94 +void get_video_firstframe(fileinfo video)
  95 +{
  96 + char buf[2048];
  97 + sprintf(buf, "ffmpeg -y -i %s -vframes 1 -ss 0 -f mjpeg -an %s.jpg", video.name.c_str(), video.name.c_str());
  98 + run_shell_cmd(buf);
  99 +}
  100 +
  101 +void merge_audio_pic(fileinfo audio, int nf, fileinfo video, char * destfile)
  102 +{
  103 + char buf[2048];
  104 + sprintf(buf, "ffmpeg -y -loop 1 -i %s.jpg -i %d_%s -loop 0 -shortest %s %s %s", video.name.c_str(), nf, audio.name.c_str(),acodec_param, vcodec_param, destfile);
  105 + run_shell_cmd(buf);
  106 +}
  107 +
  108 +void megre_audio_video(fileinfo audio, int nf, fileinfo video, char * destfile)
  109 +{
  110 + char buf[2048];
  111 + sprintf(buf, "ffmpeg -y -i %d_%s -i %s %s %s %s", nf, audio.name.c_str(), video.name.c_str(), acodec_param, vcodec_param, destfile);
  112 + run_shell_cmd(buf);
  113 +}
  114 +
  115 +void concate_files(vector<string > merged_files)
  116 +{
  117 + char buf[2048];
  118 +#ifdef WIN32
  119 + sprintf(buf, "copy /B %s ", merged_files[0].c_str());
  120 +
  121 + for (int i = 1; i < merged_files.size(); i++) {
  122 + strcat(buf, " + /B ");
  123 + strcat(buf, merged_files[i].c_str());
  124 + }
  125 +#else
  126 + strcpy(buf, "cat ");
  127 +
  128 + for (int i = 0; i < merged_files.size(); i++) {
  129 + strcat(buf, " ");
  130 + strcat(buf, merged_files[0].c_str());
  131 + }
  132 + strcat(buf ">");
  133 +#endif // WIN32
  134 + strcat(buf, " m.ts");
  135 + run_shell_cmd(buf);
  136 +}
  137 +
  138 +void adjust_dest_timecode()
  139 +{
  140 + run_shell_cmd("ffmpeg -y -i m.ts -acodec copy -vcodec copy dest.ts");
  141 +}
  142 +
  143 +int process_files()
  144 +{
  145 + vector<fileinfo> & filesaudio = media_files[type_audio];
  146 + vector<fileinfo> & filesvideo = media_files[type_video];
  147 + vector<string > merged_files;
  148 + int nv = 0;
  149 + int nf = 0;
  150 + char destfile[1024];
  151 + for (int i = 0; i < filesaudio.size(); i++){ //
  152 + fileinfo audio = filesaudio[i];
  153 + float audio_start = 0;
  154 + for (; nv < filesvideo.size(); nv++) {
  155 + fileinfo video = filesvideo[nv];
  156 + if (video.start_time - audio_start > 0.100) {
  157 + split_audio(audio, audio_start, video.start_time - audio_start, nf);
  158 + audio_start = video.start_time;
  159 + get_video_firstframe(video);
  160 + sprintf(destfile, "%d.ts", nf);
  161 + merge_audio_pic(audio, nf, video, destfile);
  162 + merged_files.push_back(destfile);
  163 + nf++;
  164 + }
  165 + if (nv != filesvideo.size() - 1) {// not the last one
  166 + split_audio(audio, video.start_time, video.end_time - video.start_time, nf);
  167 +
  168 + audio_start = video.end_time;
  169 + sprintf(destfile, "%d.ts", nf);
  170 + megre_audio_video(audio, nf, video, destfile);
  171 + merged_files.push_back(destfile);
  172 + nf++;
  173 + }
  174 + else {
  175 + split_audio(audio, video.start_time, audio.end_time - video.start_time, nf);
  176 + audio_start = video.end_time;
  177 + sprintf(destfile, "%d.ts", nf);
  178 + megre_audio_video(audio, nf, video, destfile);
  179 + merged_files.push_back(destfile);
  180 + nf++;
  181 + }
  182 + }
  183 + }
  184 +
  185 + concate_files(merged_files);
  186 + adjust_dest_timecode();
  187 + return 0;
  188 +}
  189 +
  190 +
  191 +int readfile(char * filename)
  192 +{
  193 + ifstream fin(filename);
  194 + if (!fin) {
  195 + return -1;
  196 + }
  197 + const int LINE_LENGTH = 1000;
  198 + char str[LINE_LENGTH];
  199 + while (fin.getline(str, LINE_LENGTH))
  200 + {
  201 + vector < string > res;
  202 + split(str, " ", res);
  203 + if (res.size() >= 3) {
  204 + if (res[2] == "create"){
  205 + addinfo(res[0], res[1], true);
  206 + }
  207 + else if (res[2] == "close") {
  208 + addinfo(res[0], res[1], false);
  209 + }
  210 + }
  211 + }
  212 + return 0;
  213 +}
  214 +
  215 +void load_codec_param()
  216 +{
  217 + strcpy(acodec_param, default_acodec_param);
  218 + strcpy(vcodec_param, default_vcodec_param);
  219 +}
  220 +
  221 +int main(int argc, char * argv[])
  222 +{
  223 + if (argc < 2) {
  224 + printf("%s record_info_filename [-p]");
  225 + return -1;
  226 + }
  227 +
  228 + if (readfile(argv[1]) < 0) {
  229 + printf("open file: %s error", argv[1]);
  230 + return -2;
  231 + }
  232 +
  233 +
  234 + if (argc == 3 && !strcmp(argv[2], "-p")) {
  235 + only_print = true;
  236 + }
  237 +
  238 + load_codec_param();
  239 +
  240 + process_files();
  241 +
  242 + return 0;
  243 +}
  244 +
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  3 + <ItemGroup Label="ProjectConfigurations">
  4 + <ProjectConfiguration Include="Debug|Win32">
  5 + <Configuration>Debug</Configuration>
  6 + <Platform>Win32</Platform>
  7 + </ProjectConfiguration>
  8 + <ProjectConfiguration Include="Release|Win32">
  9 + <Configuration>Release</Configuration>
  10 + <Platform>Win32</Platform>
  11 + </ProjectConfiguration>
  12 + </ItemGroup>
  13 + <PropertyGroup Label="Globals">
  14 + <ProjectGuid>{F607DD90-3E62-40BA-BF8A-185E597D646D}</ProjectGuid>
  15 + <Keyword>Win32Proj</Keyword>
  16 + <RootNamespace>merge_av</RootNamespace>
  17 + </PropertyGroup>
  18 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  19 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
  20 + <ConfigurationType>Application</ConfigurationType>
  21 + <UseDebugLibraries>true</UseDebugLibraries>
  22 + <PlatformToolset>v120</PlatformToolset>
  23 + <CharacterSet>Unicode</CharacterSet>
  24 + </PropertyGroup>
  25 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
  26 + <ConfigurationType>Application</ConfigurationType>
  27 + <UseDebugLibraries>false</UseDebugLibraries>
  28 + <PlatformToolset>v120</PlatformToolset>
  29 + <WholeProgramOptimization>true</WholeProgramOptimization>
  30 + <CharacterSet>Unicode</CharacterSet>
  31 + </PropertyGroup>
  32 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  33 + <ImportGroup Label="ExtensionSettings">
  34 + </ImportGroup>
  35 + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
  36 + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  37 + </ImportGroup>
  38 + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
  39 + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  40 + </ImportGroup>
  41 + <PropertyGroup Label="UserMacros" />
  42 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
  43 + <LinkIncremental>true</LinkIncremental>
  44 + </PropertyGroup>
  45 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
  46 + <LinkIncremental>false</LinkIncremental>
  47 + </PropertyGroup>
  48 + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
  49 + <ClCompile>
  50 + <PrecompiledHeader>Use</PrecompiledHeader>
  51 + <WarningLevel>Level3</WarningLevel>
  52 + <Optimization>Disabled</Optimization>
  53 + <PreprocessorDefinitions> _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  54 + <SDLCheck>true</SDLCheck>
  55 + </ClCompile>
  56 + <Link>
  57 + <SubSystem>Console</SubSystem>
  58 + <GenerateDebugInformation>true</GenerateDebugInformation>
  59 + </Link>
  60 + </ItemDefinitionGroup>
  61 + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
  62 + <ClCompile>
  63 + <WarningLevel>Level3</WarningLevel>
  64 + <PrecompiledHeader>Use</PrecompiledHeader>
  65 + <Optimization>MaxSpeed</Optimization>
  66 + <FunctionLevelLinking>true</FunctionLevelLinking>
  67 + <IntrinsicFunctions>true</IntrinsicFunctions>
  68 + <PreprocessorDefinitions> _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  69 + <SDLCheck>true</SDLCheck>
  70 + </ClCompile>
  71 + <Link>
  72 + <SubSystem>Console</SubSystem>
  73 + <GenerateDebugInformation>true</GenerateDebugInformation>
  74 + <EnableCOMDATFolding>true</EnableCOMDATFolding>
  75 + <OptimizeReferences>true</OptimizeReferences>
  76 + </Link>
  77 + </ItemDefinitionGroup>
  78 + <ItemGroup>
  79 + <Text Include="ReadMe.txt" />
  80 + </ItemGroup>
  81 + <ItemGroup>
  82 + <ClCompile Include="merge_av.cpp">
  83 + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
  84 + </ClCompile>
  85 + </ItemGroup>
  86 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  87 + <ImportGroup Label="ExtensionTargets">
  88 + </ImportGroup>
  89 +</Project>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  3 + <ItemGroup>
  4 + <Filter Include="源文件">
  5 + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
  6 + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
  7 + </Filter>
  8 + <Filter Include="头文件">
  9 + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
  10 + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
  11 + </Filter>
  12 + <Filter Include="资源文件">
  13 + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
  14 + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
  15 + </Filter>
  16 + </ItemGroup>
  17 + <ItemGroup>
  18 + <Text Include="ReadMe.txt" />
  19 + </ItemGroup>
  20 + <ItemGroup>
  21 + <ClCompile Include="merge_av.cpp">
  22 + <Filter>源文件</Filter>
  23 + </ClCompile>
  24 + </ItemGroup>
  25 +</Project>