正在显示
5 个修改的文件
包含
410 行增加
和
0 行删除
merge_av.sln
0 → 100644
| 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 |
merge_av/ReadMe.txt
0 → 100644
| 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 | +///////////////////////////////////////////////////////////////////////////// |
merge_av/merge_av.cpp
0 → 100644
| 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 | + |
merge_av/merge_av.vcxproj
0 → 100644
| 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> |
merge_av/merge_av.vcxproj.filters
0 → 100644
| 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> |
-
请 注册 或 登录 后发表评论