胡斌

if -t is not passed in command line, if source file codec is h264,use -vcodec copy when transcode

@@ -84,6 +84,7 @@ ffmpeg -y -i m.ts -acodec copy -vcodec copy dest.ts @@ -84,6 +84,7 @@ ffmpeg -y -i m.ts -acodec copy -vcodec copy dest.ts
84 84
85 85
86 调用ffmpeg时,视频编码参数是: -vcodec libx264 -level 3.1 -preset veryfast -g 100 -r 20 -bf 0 -vsync cfr 86 调用ffmpeg时,视频编码参数是: -vcodec libx264 -level 3.1 -preset veryfast -g 100 -r 20 -bf 0 -vsync cfr
  87 +如果源视频编码是h264,则缺省不做转码,-vcodec copy
87 音频编码参数是: -acodec copy 88 音频编码参数是: -acodec copy
88 如果要修改,windows下在merge_av.exe同目录下新建merge_av.cfg文本文件,第一行保存视频编码,第二行保存音频编码;linux 下,merge_av.cfg保存在HOME目录下的merge_av目录。 89 如果要修改,windows下在merge_av.exe同目录下新建merge_av.cfg文本文件,第一行保存视频编码,第二行保存音频编码;linux 下,merge_av.cfg保存在HOME目录下的merge_av目录。
89 90
@@ -100,6 +101,9 @@ ffmpeg -y -loop 1 -i D:\Merge_av\blank.jpg -i 61712260_20171122130331753.aac -lo @@ -100,6 +101,9 @@ ffmpeg -y -loop 1 -i D:\Merge_av\blank.jpg -i 61712260_20171122130331753.aac -lo
100 linux(linux下,假定HOME目录为/home/hubin): 101 linux(linux下,假定HOME目录为/home/hubin):
101 ffmpeg -y -loop 1 -i /home/hubin/merge_av/blank.jpg -i 61712260_20171122130331753.aac -loop 0 -shortest -acodec copy -vcodec libx264 -level 3.1 -preset veryfast -g 40 -r 20 dest.ts 102 ffmpeg -y -loop 1 -i /home/hubin/merge_av/blank.jpg -i 61712260_20171122130331753.aac -loop 0 -shortest -acodec copy -vcodec libx264 -level 3.1 -preset veryfast -g 40 -r 20 dest.ts
102 103
  104 +-c 把输入文件转换为ts,不做合并处理(输入的是音视频都存在的mp4文件)
  105 +-t 如果视频是h264,也做转码。
  106 +
103 107
104 108
105 109
@@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
12 bool only_print = false; 12 bool only_print = false;
13 bool keep_tmp_files = false; 13 bool keep_tmp_files = false;
14 bool only_convert_mp4 = false; 14 bool only_convert_mp4 = false;
  15 +bool recodec_h264 = false;
15 using namespace std; 16 using namespace std;
16 17
17 enum media_type{ 18 enum media_type{
@@ -31,6 +32,7 @@ public: @@ -31,6 +32,7 @@ public:
31 string name; 32 string name;
32 int index; 33 int index;
33 media_type m_type; 34 media_type m_type;
  35 + bool is_h264;
34 }; 36 };
35 37
36 class media_info { 38 class media_info {
@@ -44,6 +46,7 @@ public: @@ -44,6 +46,7 @@ public:
44 int index; 46 int index;
45 media_type m_type; 47 media_type m_type;
46 timestamp_type t_type; 48 timestamp_type t_type;
  49 + bool is_h264;
47 }; 50 };
48 51
49 52
@@ -97,6 +100,7 @@ void get_config_path(){ @@ -97,6 +100,7 @@ void get_config_path(){
97 } 100 }
98 101
99 const char * default_vcodec_param = "-vcodec libx264 -level 3.1 -preset veryfast -g 100 -r 20 -bf 0 -vsync cfr"; 102 const char * default_vcodec_param = "-vcodec libx264 -level 3.1 -preset veryfast -g 100 -r 20 -bf 0 -vsync cfr";
  103 +const char * copy_h264_codec_param = "-vcodec copy";
100 const char * default_acodec_param = "-acodec copy"; 104 const char * default_acodec_param = "-acodec copy";
101 105
102 char vcodec_param[1024]; 106 char vcodec_param[1024];
@@ -113,6 +117,7 @@ void addinfo(string t, string name, bool bstart){ @@ -113,6 +117,7 @@ void addinfo(string t, string name, bool bstart){
113 f.end_time = f.start_time; 117 f.end_time = f.start_time;
114 f.name = name; 118 f.name = name;
115 f.m_type = mtype; 119 f.m_type = mtype;
  120 + f.is_h264 = false; //default to false when init
116 121
117 if (!first_time_set) { 122 if (!first_time_set) {
118 first_time_set = true; 123 first_time_set = true;
@@ -178,24 +183,39 @@ void merge_audio_pic(const char * audio, const char * picfile, const char * dest @@ -178,24 +183,39 @@ void merge_audio_pic(const char * audio, const char * picfile, const char * dest
178 } 183 }
179 184
180 185
181 -void merge_audio_video(const char * audio, const char * video, const char * destfile) 186 +void merge_audio_video(const char * audio, const char * video, const char * destfile, bool bH264)
182 { 187 {
183 char buf[2048]; 188 char buf[2048];
184 - sprintf(buf, "ffmpeg -y -i %s -i %s %s %s %s", audio, video, acodec_param, vcodec_param, destfile); 189 + if (false == recodec_h264 && true == bH264) {
  190 + sprintf(buf, "ffmpeg -y -i %s -i %s %s %s %s", audio, video, acodec_param, copy_h264_codec_param, destfile);
  191 + }
  192 + else {
  193 + sprintf(buf, "ffmpeg -y -i %s -i %s %s %s %s", audio, video, acodec_param, vcodec_param, destfile);
  194 + }
185 run_shell_cmd(buf); 195 run_shell_cmd(buf);
186 } 196 }
187 197
188 -void convert_video_to_ts(const char * video, const char * destfile) 198 +void convert_video_to_ts(const char * video, const char * destfile, bool bH264)
189 { 199 {
190 char buf[2048]; 200 char buf[2048];
191 - sprintf(buf, "ffmpeg -y -i %s %s %s %s",video, acodec_param, vcodec_param, destfile); 201 + if (false == recodec_h264 && true == bH264) {
  202 + sprintf(buf, "ffmpeg -y -i %s %s %s %s", video, acodec_param, copy_h264_codec_param, destfile);
  203 + }
  204 + else {
  205 + sprintf(buf, "ffmpeg -y -i %s %s %s %s", video, acodec_param, vcodec_param, destfile);
  206 + }
192 run_shell_cmd(buf); 207 run_shell_cmd(buf);
193 } 208 }
194 209
195 -void merge_video_silence(fileinfo video, const char * aacfile, const char * destfile) 210 +void merge_video_silence(fileinfo video, const char * aacfile, const char * destfile, bool bH264)
196 { 211 {
197 char buf[2048]; 212 char buf[2048];
198 - sprintf(buf, "ffmpeg -y -i %s -i %s -shortest %s %s %s", aacfile, video.name.c_str(), acodec_param, vcodec_param, destfile); 213 + if (false == recodec_h264 && true == bH264) {
  214 + sprintf(buf, "ffmpeg -y -i %s -i %s -shortest %s %s %s", aacfile, video.name.c_str(), acodec_param, copy_h264_codec_param, destfile);
  215 + }
  216 + else {
  217 + sprintf(buf, "ffmpeg -y -i %s -i %s -shortest %s %s %s", aacfile, video.name.c_str(), acodec_param, vcodec_param, destfile);
  218 + }
199 run_shell_cmd(buf); 219 run_shell_cmd(buf);
200 } 220 }
201 221
@@ -252,7 +272,7 @@ void removefiles(vector<string> files) @@ -252,7 +272,7 @@ void removefiles(vector<string> files)
252 } 272 }
253 } 273 }
254 274
255 -float parse_ffmpeg_duration(const char * file) 275 +float parse_ffmpeg_duration(const char * file, bool * beH264 = NULL)
256 { 276 {
257 FILE * fp = fopen(file, "rb"); 277 FILE * fp = fopen(file, "rb");
258 if (!fp) { 278 if (!fp) {
@@ -273,6 +293,16 @@ float parse_ffmpeg_duration(const char * file) @@ -273,6 +293,16 @@ float parse_ffmpeg_duration(const char * file)
273 remove_file(file); 293 remove_file(file);
274 } 294 }
275 295
  296 + if (beH264){
  297 + *beH264 = false;
  298 + char * p = strstr(content, "Video:");
  299 + if (p){
  300 + if (strstr(p, "h264")){
  301 + *beH264 = true;
  302 + }
  303 + }
  304 + }
  305 +
276 char * pDuration = strstr(content, "Duration:"); 306 char * pDuration = strstr(content, "Duration:");
277 if (!pDuration){ 307 if (!pDuration){
278 printf("\ncan't find 'Duration:' in %s\n", file); 308 printf("\ncan't find 'Duration:' in %s\n", file);
@@ -307,7 +337,7 @@ float parse_ffmpeg_duration(const char * file) @@ -307,7 +337,7 @@ float parse_ffmpeg_duration(const char * file)
307 return hour * 3600 + minute * 60 + sec; 337 return hour * 3600 + minute * 60 + sec;
308 } 338 }
309 339
310 -float get_mp4_duration(const char *mediafile, bool bVideo) 340 +float get_mp4_duration(const char *mediafile, bool bVideo, bool * bH264)
311 { 341 {
312 char buf[2048]; 342 char buf[2048];
313 343
@@ -345,20 +375,20 @@ float get_mp4_duration(const char *mediafile, bool bVideo) @@ -345,20 +375,20 @@ float get_mp4_duration(const char *mediafile, bool bVideo)
345 375
346 376
347 sprintf(buf, "%s.txt", mediafile); 377 sprintf(buf, "%s.txt", mediafile);
348 - return parse_ffmpeg_duration(buf); 378 + return parse_ffmpeg_duration(buf, bH264);
349 } 379 }
350 380
351 #ifdef WIN32 381 #ifdef WIN32
352 #define strcasecmp _stricmp 382 #define strcasecmp _stricmp
353 #endif 383 #endif
354 384
355 -float get_file_duration(const char *mediafile, bool bVideo) 385 +float get_file_duration(const char *mediafile, bool bVideo, bool * beH264 = NULL)
356 { 386 {
357 char buf[2048]; 387 char buf[2048];
358 int len = strlen(mediafile); 388 int len = strlen(mediafile);
359 if (len > 3) { 389 if (len > 3) {
360 if (!strcasecmp(mediafile + len - 4, ".mp4")) { 390 if (!strcasecmp(mediafile + len - 4, ".mp4")) {
361 - return get_mp4_duration(mediafile, bVideo); 391 + return get_mp4_duration(mediafile, bVideo, beH264);
362 } 392 }
363 } 393 }
364 if (bVideo){ 394 if (bVideo){
@@ -384,7 +414,8 @@ float get_file_duration(const char *mediafile, bool bVideo) @@ -384,7 +414,8 @@ float get_file_duration(const char *mediafile, bool bVideo)
384 414
385 415
386 sprintf(buf, "%s.txt", mediafile); 416 sprintf(buf, "%s.txt", mediafile);
387 - return parse_ffmpeg_duration(buf); 417 + float duration = parse_ffmpeg_duration(buf, beH264);
  418 + return duration;
388 } 419 }
389 420
390 void get_duration_from_video_file() 421 void get_duration_from_video_file()
@@ -394,11 +425,13 @@ void get_duration_from_video_file() @@ -394,11 +425,13 @@ void get_duration_from_video_file()
394 425
395 for (int i = 0; i < media_files.size(); i++){ 426 for (int i = 0; i < media_files.size(); i++){
396 if (media_files[i].m_type == mt_video) { 427 if (media_files[i].m_type == mt_video) {
397 - float duration = get_file_duration(media_files[i].name.c_str(), true); 428 + bool bH264 = false;
  429 + float duration = get_file_duration(media_files[i].name.c_str(), true, &bH264);
398 if (duration >= 0.1) { 430 if (duration >= 0.1) {
399 printf("file:%s , duration in recording file: %.3f, duration parsed from file: %.3f\n", media_files[i].name.c_str(), media_files[i].end_time - media_files[i].start_time, duration); 431 printf("file:%s , duration in recording file: %.3f, duration parsed from file: %.3f\n", media_files[i].name.c_str(), media_files[i].end_time - media_files[i].start_time, duration);
400 media_files[i].end_time = media_files[i].start_time + duration; 432 media_files[i].end_time = media_files[i].start_time + duration;
401 } 433 }
  434 + media_files[i].is_h264 = bH264;
402 } 435 }
403 } 436 }
404 437
@@ -492,6 +525,7 @@ void add_media_infos() @@ -492,6 +525,7 @@ void add_media_infos()
492 m.t_type = tt_start; 525 m.t_type = tt_start;
493 m.duration = f.end_time - f.start_time; 526 m.duration = f.end_time - f.start_time;
494 m.type_time = m.start_time; 527 m.type_time = m.start_time;
  528 + m.is_h264 = f.is_h264;
495 add_media_info(m); 529 add_media_info(m);
496 m.t_type = tt_end; 530 m.t_type = tt_end;
497 m.type_time = m.end_time; 531 m.type_time = m.end_time;
@@ -512,10 +546,9 @@ void init() @@ -512,10 +546,9 @@ void init()
512 strcpy(silence_aac_file, cfg_path); 546 strcpy(silence_aac_file, cfg_path);
513 strcat(silence_aac_file, "silence.aac"); 547 strcat(silence_aac_file, "silence.aac");
514 548
515 - if (only_convert_mp4 == false) {  
516 - check_audio_duration();  
517 - get_duration_from_video_file();  
518 - } 549 + check_audio_duration();
  550 + get_duration_from_video_file();
  551 +
519 add_media_infos(); 552 add_media_infos();
520 553
521 nv = 0; 554 nv = 0;
@@ -570,7 +603,7 @@ int merge_audio_video(vector<media_info> & files) @@ -570,7 +603,7 @@ int merge_audio_video(vector<media_info> & files)
570 603
571 604
572 sprintf(destfile, "%d.ts", nf); 605 sprintf(destfile, "%d.ts", nf);
573 - merge_audio_video(audio_file, video.name.c_str(), destfile); 606 + merge_audio_video(audio_file, video.name.c_str(), destfile, video.is_h264);
574 merged_files.push_back(destfile); 607 merged_files.push_back(destfile);
575 nf++; 608 nf++;
576 609
@@ -804,14 +837,14 @@ int process_files_to_1file(const char * output_dest_file) @@ -804,14 +837,14 @@ int process_files_to_1file(const char * output_dest_file)
804 else { 837 else {
805 if (media_files.size() == 1){ 838 if (media_files.size() == 1){
806 fileinfo video = media_files[0]; 839 fileinfo video = media_files[0];
807 - merge_video_silence(video, silence_aac_file, "dest.ts"); 840 + merge_video_silence(video, silence_aac_file, "dest.ts", video.is_h264);
808 return 0; 841 return 0;
809 } 842 }
810 843
811 for (int i = 0; i < media_files.size(); i++){ 844 for (int i = 0; i < media_files.size(); i++){
812 fileinfo video = media_files[i]; 845 fileinfo video = media_files[i];
813 sprintf(destfile, "%d.ts", nf); 846 sprintf(destfile, "%d.ts", nf);
814 - merge_video_silence(video, silence_aac_file, destfile); 847 + merge_video_silence(video, silence_aac_file, destfile, video.is_h264);
815 merged_files.push_back(destfile); 848 merged_files.push_back(destfile);
816 nf++; 849 nf++;
817 } 850 }
@@ -983,7 +1016,7 @@ int process_files() @@ -983,7 +1016,7 @@ int process_files()
983 for (int i = 0; i < media_files.size(); i++){ 1016 for (int i = 0; i < media_files.size(); i++){
984 fileinfo video = media_files[i]; 1017 fileinfo video = media_files[i];
985 get_output_file_name(i, video.name.c_str(), outputfile); 1018 get_output_file_name(i, video.name.c_str(), outputfile);
986 - merge_video_silence(video, silence_aac_file, outputfile); 1019 + merge_video_silence(video, silence_aac_file, outputfile, video.is_h264);
987 save_out_info(video.start_time, outputfile); 1020 save_out_info(video.start_time, outputfile);
988 } 1021 }
989 } 1022 }
@@ -1018,7 +1051,7 @@ int process_only_mp4_files() @@ -1018,7 +1051,7 @@ int process_only_mp4_files()
1018 continue; 1051 continue;
1019 } 1052 }
1020 get_output_file_name(i, video.name.c_str(), outputfile); 1053 get_output_file_name(i, video.name.c_str(), outputfile);
1021 - convert_video_to_ts(video.name.c_str(), outputfile); 1054 + convert_video_to_ts(video.name.c_str(), outputfile, video.is_h264);
1022 save_out_info(video.start_time, outputfile); 1055 save_out_info(video.start_time, outputfile);
1023 } 1056 }
1024 1057
@@ -1105,6 +1138,7 @@ int main(int argc, char * argv[]) @@ -1105,6 +1138,7 @@ int main(int argc, char * argv[])
1105 printf("\n -p :only print the command,don't run ffmpeg"); 1138 printf("\n -p :only print the command,don't run ffmpeg");
1106 printf("\n -k :keep the temp files\n"); 1139 printf("\n -k :keep the temp files\n");
1107 printf("\n -c :only convert mp4 files\n"); 1140 printf("\n -c :only convert mp4 files\n");
  1141 + printf("\n -t :recodec h264\n");
1108 return -1; 1142 return -1;
1109 } 1143 }
1110 1144
@@ -1123,6 +1157,9 @@ int main(int argc, char * argv[]) @@ -1123,6 +1157,9 @@ int main(int argc, char * argv[])
1123 else if (!strcmp(argv[i], "-c")){ 1157 else if (!strcmp(argv[i], "-c")){
1124 only_convert_mp4 = true; 1158 only_convert_mp4 = true;
1125 } 1159 }
  1160 + else if (!strcmp(argv[i], "-t")){
  1161 + recodec_h264 = true;
  1162 + }
1126 } 1163 }
1127 1164
1128 get_outinfo_file_name(argv[1]); 1165 get_outinfo_file_name(argv[1]);