if -t is not passed in command line, if source file codec is h264,use -vcodec copy when transcode
正在显示
2 个修改的文件
包含
63 行增加
和
22 行删除
| @@ -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]); |
-
请 注册 或 登录 后发表评论