浏览代码

正在添加 ffmpeg 的解析函数,获取视频的音频、字幕信息

Signed-off-by: allan716 <[email protected]>
allan716 4 年之前
父节点
当前提交
6bc1a0e217

+ 1 - 0
.gitignore

@@ -53,3 +53,4 @@
 /internal/pkg/sub_timeline_fixer/Logs
 /internal/pkg/sub_timeline_fixer/config.yaml
 /SubFixCache
+/TestData/ffmpeg/test

+ 135 - 0
TestData/ffmpeg/org/R&M S05E10-video_stream.json

@@ -0,0 +1,135 @@
+{
+    "streams": [
+        {
+            "index": 0,
+            "codec_name": "h264",
+            "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
+            "profile": "High",
+            "codec_type": "video",
+            "codec_time_base": "1001/48000",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "width": 1920,
+            "height": 1080,
+            "coded_width": 1920,
+            "coded_height": 1088,
+            "closed_captions": 1,
+            "has_b_frames": 2,
+            "sample_aspect_ratio": "1:1",
+            "display_aspect_ratio": "16:9",
+            "pix_fmt": "yuv420p",
+            "level": 41,
+            "chroma_location": "left",
+            "field_order": "progressive",
+            "refs": 1,
+            "is_avc": "true",
+            "nal_length_size": "4",
+            "r_frame_rate": "24000/1001",
+            "avg_frame_rate": "24000/1001",
+            "time_base": "1/1000",
+            "start_pts": 0,
+            "start_time": "0.000000",
+            "bits_per_raw_sample": "8",
+            "disposition": {
+                "default": 1,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            }
+        },
+        {
+            "index": 1,
+            "codec_name": "aac",
+            "codec_long_name": "AAC (Advanced Audio Coding)",
+            "profile": "LC",
+            "codec_type": "audio",
+            "codec_time_base": "1/44100",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "sample_fmt": "fltp",
+            "sample_rate": "44100",
+            "channels": 2,
+            "channel_layout": "stereo",
+            "bits_per_sample": 0,
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/1000",
+            "start_pts": 0,
+            "start_time": "0.000000",
+            "disposition": {
+                "default": 1,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "language": "eng"
+            }
+        },
+        {
+            "index": 2,
+            "codec_name": "subrip",
+            "codec_long_name": "SubRip subtitle",
+            "codec_type": "subtitle",
+            "codec_time_base": "0/1",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/1000",
+            "start_pts": 0,
+            "start_time": "0.000000",
+            "duration_ts": 1433925,
+            "duration": "1433.925000",
+            "disposition": {
+                "default": 0,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "language": "eng",
+                "title": "English"
+            }
+        }
+    ],
+    "format": {
+        "filename": "X:\\连续剧\\瑞克和莫蒂 (2013)\\Season 5\\Rick and Morty - S05E10 - Rickmurai Jack WEBRip-1080p.mkv",
+        "nb_streams": 3,
+        "nb_programs": 0,
+        "format_name": "matroska,webm",
+        "format_long_name": "Matroska / WebM",
+        "start_time": "0.000000",
+        "duration": "1433.925000",
+        "size": "840300642",
+        "bit_rate": "4688114",
+        "probe_score": 100,
+        "tags": {
+            "encoder": "libebml v1.4.0 + libmatroska v1.6.1"
+        }
+    }
+}

+ 387 - 0
TestData/ffmpeg/org/千与千寻-video_stream.json

@@ -0,0 +1,387 @@
+{
+    "streams": [
+        {
+            "index": 0,
+            "codec_name": "hevc",
+            "codec_long_name": "H.265 / HEVC (High Efficiency Video Coding)",
+            "profile": "Main 10",
+            "codec_type": "video",
+            "codec_time_base": "1001/24000",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "width": 1920,
+            "height": 1036,
+            "coded_width": 1920,
+            "coded_height": 1040,
+            "closed_captions": 0,
+            "has_b_frames": 2,
+            "sample_aspect_ratio": "1:1",
+            "display_aspect_ratio": "480:259",
+            "pix_fmt": "yuv420p10le",
+            "level": 120,
+            "color_range": "tv",
+            "color_space": "bt709",
+            "color_transfer": "bt709",
+            "color_primaries": "bt709",
+            "refs": 1,
+            "r_frame_rate": "24000/1001",
+            "avg_frame_rate": "24000/1001",
+            "time_base": "1/1000",
+            "start_pts": 7,
+            "start_time": "0.007000",
+            "disposition": {
+                "default": 1,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "BPS-eng": "8543726",
+                "DURATION-eng": "02:04:32.757000000",
+                "NUMBER_OF_FRAMES-eng": "179167",
+                "NUMBER_OF_BYTES-eng": "7980648685",
+                "_STATISTICS_WRITING_APP-eng": "mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit",
+                "_STATISTICS_WRITING_DATE_UTC-eng": "2020-11-16 19:43:47",
+                "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES"
+            }
+        },
+        {
+            "index": 1,
+            "codec_name": "opus",
+            "codec_long_name": "Opus (Opus Interactive Audio Codec)",
+            "codec_type": "audio",
+            "codec_time_base": "1/48000",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "sample_fmt": "fltp",
+            "sample_rate": "48000",
+            "channels": 2,
+            "channel_layout": "stereo",
+            "bits_per_sample": 0,
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/1000",
+            "start_pts": -7,
+            "start_time": "-0.007000",
+            "disposition": {
+                "default": 1,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "language": "jpn",
+                "BPS-eng": "251227",
+                "DURATION-eng": "02:04:32.281000000",
+                "NUMBER_OF_FRAMES-eng": "373614",
+                "NUMBER_OF_BYTES-eng": "234655414",
+                "_STATISTICS_WRITING_APP-eng": "mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit",
+                "_STATISTICS_WRITING_DATE_UTC-eng": "2020-11-16 19:43:47",
+                "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES"
+            }
+        },
+        {
+            "index": 2,
+            "codec_name": "opus",
+            "codec_long_name": "Opus (Opus Interactive Audio Codec)",
+            "codec_type": "audio",
+            "codec_time_base": "1/48000",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "sample_fmt": "fltp",
+            "sample_rate": "48000",
+            "channels": 7,
+            "channel_layout": "6.1",
+            "bits_per_sample": 0,
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/1000",
+            "start_pts": -7,
+            "start_time": "-0.007000",
+            "disposition": {
+                "default": 0,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "language": "jpn",
+                "BPS-eng": "551850",
+                "DURATION-eng": "02:04:32.281000000",
+                "NUMBER_OF_FRAMES-eng": "373614",
+                "NUMBER_OF_BYTES-eng": "515447735",
+                "_STATISTICS_WRITING_APP-eng": "mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit",
+                "_STATISTICS_WRITING_DATE_UTC-eng": "2020-11-16 19:43:47",
+                "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES"
+            }
+        },
+        {
+            "index": 3,
+            "codec_name": "ac3",
+            "codec_long_name": "ATSC A/52A (AC-3)",
+            "codec_type": "audio",
+            "codec_time_base": "1/48000",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "sample_fmt": "fltp",
+            "sample_rate": "48000",
+            "channels": 6,
+            "channel_layout": "5.1(side)",
+            "bits_per_sample": 0,
+            "dmix_mode": "-1",
+            "ltrt_cmixlev": "-1.000000",
+            "ltrt_surmixlev": "-1.000000",
+            "loro_cmixlev": "-1.000000",
+            "loro_surmixlev": "-1.000000",
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/1000",
+            "start_pts": 2,
+            "start_time": "0.002000",
+            "bit_rate": "576000",
+            "disposition": {
+                "default": 0,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "language": "chi",
+                "BPS-eng": "576000",
+                "DURATION-eng": "02:04:32.800000000",
+                "NUMBER_OF_FRAMES-eng": "233525",
+                "NUMBER_OF_BYTES-eng": "538041600",
+                "_STATISTICS_WRITING_APP-eng": "mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit",
+                "_STATISTICS_WRITING_DATE_UTC-eng": "2020-11-16 19:43:47",
+                "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES"
+            }
+        },
+        {
+            "index": 4,
+            "codec_name": "ass",
+            "codec_long_name": "ASS (Advanced SSA) subtitle",
+            "codec_type": "subtitle",
+            "codec_time_base": "0/1",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/1000",
+            "start_pts": -7,
+            "start_time": "-0.007000",
+            "duration_ts": 7472802,
+            "duration": "7472.802000",
+            "disposition": {
+                "default": 1,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "title": "SC",
+                "BPS-eng": "131",
+                "DURATION-eng": "02:04:08.310000000",
+                "NUMBER_OF_FRAMES-eng": "2223",
+                "NUMBER_OF_BYTES-eng": "122445",
+                "_STATISTICS_WRITING_APP-eng": "mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit",
+                "_STATISTICS_WRITING_DATE_UTC-eng": "2020-11-16 19:43:47",
+                "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES"
+            }
+        },
+        {
+            "index": 5,
+            "codec_name": "ass",
+            "codec_long_name": "ASS (Advanced SSA) subtitle",
+            "codec_type": "subtitle",
+            "codec_time_base": "0/1",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/1000",
+            "start_pts": -7,
+            "start_time": "-0.007000",
+            "duration_ts": 7472802,
+            "duration": "7472.802000",
+            "disposition": {
+                "default": 0,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "title": "TC",
+                "BPS-eng": "131",
+                "DURATION-eng": "02:04:08.310000000",
+                "NUMBER_OF_FRAMES-eng": "2223",
+                "NUMBER_OF_BYTES-eng": "122448",
+                "_STATISTICS_WRITING_APP-eng": "mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit",
+                "_STATISTICS_WRITING_DATE_UTC-eng": "2020-11-16 19:43:47",
+                "_STATISTICS_TAGS-eng": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES"
+            }
+        },
+        {
+            "index": 6,
+            "codec_name": "ttf",
+            "codec_long_name": "TrueType font",
+            "codec_type": "attachment",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/90000",
+            "start_pts": -630,
+            "start_time": "-0.007000",
+            "duration_ts": 672552180,
+            "duration": "7472.802000",
+            "disposition": {
+                "default": 0,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "filename": "鏂规鍑嗗渾_GBK.TTF",
+                "mimetype": "application/x-truetype-font"
+            }
+        },
+        {
+            "index": 7,
+            "codec_name": "otf",
+            "codec_long_name": "OpenType font",
+            "codec_type": "attachment",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/90000",
+            "start_pts": -630,
+            "start_time": "-0.007000",
+            "duration_ts": 672552180,
+            "duration": "7472.802000",
+            "disposition": {
+                "default": 0,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "filename": "A-OTF-ShinMGoPro-DeBold.otf",
+                "mimetype": "application/vnd.ms-opentype"
+            }
+        },
+        {
+            "index": 8,
+            "codec_name": "ttf",
+            "codec_long_name": "TrueType font",
+            "codec_type": "attachment",
+            "codec_tag_string": "[0][0][0][0]",
+            "codec_tag": "0x0000",
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/90000",
+            "start_pts": -630,
+            "start_time": "-0.007000",
+            "duration_ts": 672552180,
+            "duration": "7472.802000",
+            "disposition": {
+                "default": 0,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0,
+                "timed_thumbnails": 0
+            },
+            "tags": {
+                "filename": "FZCuYuan-M03.ttf",
+                "mimetype": "application/x-truetype-font"
+            }
+        }
+    ],
+    "format": {
+        "filename": "X:\\电影\\千与千寻 (2001)\\千与千寻 (2001) 1080p Opus.mkv",
+        "nb_streams": 9,
+        "nb_programs": 0,
+        "format_name": "matroska,webm",
+        "format_long_name": "Matroska / WebM",
+        "start_time": "-0.007000",
+        "duration": "7472.802000",
+        "size": "9297047262",
+        "bit_rate": "9952943",
+        "probe_score": 100,
+        "tags": {
+            "encoder": "libebml v1.4.0 + libmatroska v1.6.0",
+            "creation_time": "2020-11-16T19:43:47.000000Z"
+        }
+    }
+}

+ 7 - 0
go.mod

@@ -67,6 +67,7 @@ require (
 	github.com/andybalholm/brotli v1.0.0 // indirect
 	github.com/andybalholm/cascadia v1.2.0 // indirect
 	github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 // indirect
+	github.com/aws/aws-sdk-go v1.38.20 // indirect
 	github.com/bodgit/plumbing v1.1.0 // indirect
 	github.com/bodgit/windows v1.0.0 // indirect
 	github.com/connesc/cipherio v0.2.1 // indirect
@@ -76,6 +77,7 @@ require (
 	github.com/hashicorp/go-multierror v1.1.0 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
+	github.com/jmespath/go-jmespath v0.4.0 // indirect
 	github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
 	github.com/klauspost/pgzip v1.2.4 // indirect
 	github.com/mattn/go-isatty v0.0.12 // indirect
@@ -85,6 +87,11 @@ require (
 	github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
 	github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 // indirect
 	github.com/subosito/gotenv v1.2.0 // indirect
+	github.com/tidwall/gjson v1.9.4 // indirect
+	github.com/tidwall/match v1.1.1 // indirect
+	github.com/tidwall/pretty v1.2.0 // indirect
+	github.com/u2takey/ffmpeg-go v0.3.0 // indirect
+	github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7 // indirect
 	github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
 	github.com/ysmood/goob v0.3.0 // indirect
 	github.com/ysmood/leakless v0.7.0 // indirect

+ 31 - 0
go.sum

@@ -48,6 +48,8 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC
 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to=
 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aws/aws-sdk-go v1.38.20 h1:QbzNx/tdfATbdKfubBpkt84OM6oBkxQZRw6+bW2GyeA=
+github.com/aws/aws-sdk-go v1.38.20/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
 github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
 github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
 github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
@@ -82,6 +84,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
+github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
 github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
 github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
@@ -111,6 +115,7 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
 github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
 github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4=
 github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
 github.com/go-rod/rod v0.101.7 h1:kbI5CNvcRhf7feybBln4xDutsM0mbsF0ENNZfKcF6WA=
@@ -152,6 +157,7 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
 github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
@@ -195,6 +201,9 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
 github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
 github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
 github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
@@ -270,6 +279,8 @@ github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWk
 github.com/nzlov/chardet v0.0.0-20190815145004-022cbcf483f9 h1:Fr9qvoS1YZWpT+tlwMd2ILFxhcYQZ9neP4zbw7J25zQ=
 github.com/nzlov/chardet v0.0.0-20190815145004-022cbcf483f9/go.mod h1:1TeXuGo9we3KPG7S3u3TfJ3KcPbM2j2dOGy56Y6ktnI=
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
 github.com/panjf2000/ants/v2 v2.4.5 h1:kcGvjXB7ea0MrzzszpnlVFthhYKoFxLi75nRbsq01HY=
 github.com/panjf2000/ants/v2 v2.4.5/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
@@ -323,6 +334,7 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 github.com/spf13/afero v1.4.1 h1:asw9sl74539yqavKaglDM5hFpdJVK0Y5Dr/JOgQ89nQ=
 github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@@ -348,7 +360,20 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 h1:J6v8awz+me+xeb/cUTotKgceAYouhIB3pjzgRd6IlGk=
 github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816/go.mod h1:tzym/CEb5jnFI+Q0k4Qq3+LvRF4gO3E2pxS8fHP8jcA=
+github.com/tidwall/gjson v1.6.3/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0=
+github.com/tidwall/gjson v1.9.4 h1:oNis7dk9Rs3dKJNNigXZT1MTOiJeBtpurn+IpCB75MY=
+github.com/tidwall/gjson v1.9.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
+github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
+github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
+github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
+github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/u2takey/ffmpeg-go v0.3.0 h1:oUHSOWat6LaSX2qSA2P3mBTSbuxxMyW9LP91M7ROZbs=
+github.com/u2takey/ffmpeg-go v0.3.0/go.mod h1:fYXsX59gpUyHRgO9++fANdWbNcs+500nIZPCXkquL9o=
+github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7 h1:PT7mE8HJE1mwaSazrOdSeByJ1FoV33/fHUZrBB+zwVU=
+github.com/u2takey/go-utils v0.0.0-20200713025200-4704d09fc2c7/go.mod h1:ATqKFpgjUIlhGRs8j59gXmu8Cmpo1QQEHV6vwu1hs28=
 github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
 github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
 github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
@@ -378,6 +403,7 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU=
 go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg=
+gocv.io/x/gocv v0.25.0/go.mod h1:Rar2PS6DV+T4FL+PM535EImD/h13hGVaHhnCu1xarBs=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -405,6 +431,7 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86h
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -450,6 +477,7 @@ golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
 golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -483,6 +511,7 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -603,6 +632,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -652,3 +682,4 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

+ 7 - 8
internal/downloader.go

@@ -25,7 +25,6 @@ import (
 	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"os"
-	"path"
 	"path/filepath"
 	"sync"
 )
@@ -296,7 +295,7 @@ func (d Downloader) DownloadSub4Series(dir string) error {
 			} else {
 				// 先进性 emby_helper api 的操作,读取需要更新字幕的项目
 				seriesInfo, organizeSubFiles, err = subSupplierHub.DownloadSub4SeriesFromEmby(
-					path.Join(dir, inData.OneVideoFullPath),
+					filepath.Join(dir, inData.OneVideoFullPath),
 					d.seriesSubNeedDlMap[inData.OneVideoFullPath], inData.Index)
 				if err != nil {
 					d.log.Errorln("subSupplierHub.DownloadSub4Series", inData.OneVideoFullPath, err)
@@ -514,9 +513,9 @@ func (d Downloader) saveFullSeasonSub(seriesInfo *series.SeriesInfo, organizeSub
 		}
 		for _, sub := range subs {
 			subFileName := filepath.Base(sub)
-			newSeasonSubRootPath := path.Join(seriesInfo.DirPath, "Sub_"+seasonKey)
+			newSeasonSubRootPath := filepath.Join(seriesInfo.DirPath, "Sub_"+seasonKey)
 			_ = os.MkdirAll(newSeasonSubRootPath, os.ModePerm)
-			newSubFullPath := path.Join(newSeasonSubRootPath, subFileName)
+			newSubFullPath := filepath.Join(newSeasonSubRootPath, subFileName)
 			err := pkg.CopyFile(sub, newSubFullPath)
 			if err != nil {
 				d.log.Errorln("saveFullSeasonSub", subFileName, err)
@@ -547,13 +546,13 @@ func (d Downloader) writeSubFile2VideoPath(videoFileFullPath string, finalSubFil
 	videoRootPath := filepath.Dir(videoFileFullPath)
 	subNewName, subNewNameWithDefault, _ := d.subFormatter.GenerateMixSubName(videoFileFullPath, finalSubFile.Ext, finalSubFile.Lang, extraSubPreName)
 
-	desSubFullPath := path.Join(videoRootPath, subNewName)
+	desSubFullPath := filepath.Join(videoRootPath, subNewName)
 	if setDefault == true {
 		// 先判断没有 default 的字幕是否存在了,在的话,先删除,然后再写入
 		if pkg.IsFile(desSubFullPath) == true {
 			_ = os.Remove(desSubFullPath)
 		}
-		desSubFullPath = path.Join(videoRootPath, subNewNameWithDefault)
+		desSubFullPath = filepath.Join(videoRootPath, subNewNameWithDefault)
 	}
 
 	if skipExistFile == true {
@@ -580,14 +579,14 @@ func (d Downloader) copySubFile2DesFolder(desFolder string, subFiles []string) e
 
 	// 需要进行字幕文件的缓存
 	// 把缓存的文件夹新建出来
-	desFolderFullPath := path.Join(desFolder, common.SubTmpFolderName)
+	desFolderFullPath := filepath.Join(desFolder, common.SubTmpFolderName)
 	err := os.MkdirAll(desFolderFullPath, os.ModePerm)
 	if err != nil {
 		return err
 	}
 	// 复制下载在 tmp 文件夹中的字幕文件到视频文件夹下面
 	for _, subFile := range subFiles {
-		newFn := path.Join(desFolderFullPath, filepath.Base(subFile))
+		newFn := filepath.Join(desFolderFullPath, filepath.Base(subFile))
 		err = pkg.CopyFile(subFile, newFn)
 		if err != nil {
 			return err

+ 2 - 2
internal/logic/emby_helper/embyhelper.go

@@ -75,10 +75,10 @@ func (em *EmbyHelper) GetRecentlyAddVideoList(movieRootDir, seriesRootDir string
 	}
 	// 拼接绝对路径
 	for i, info := range noSubMovieList {
-		noSubMovieList[i].VideoFileFullPath = path.Join(movieRootDir, info.VideoFileRelativePath)
+		noSubMovieList[i].VideoFileFullPath = filepath.Join(movieRootDir, info.VideoFileRelativePath)
 	}
 	for i, info := range noSubSeriesList {
-		noSubSeriesList[i].VideoFileFullPath = path.Join(seriesRootDir, info.VideoFileRelativePath)
+		noSubSeriesList[i].VideoFileFullPath = filepath.Join(seriesRootDir, info.VideoFileRelativePath)
 	}
 	// 需要将连续剧零散的每一集,进行合并到一个连续剧下面,也就是这个连续剧有那些需要更新的
 	var seriesMap = make(map[string][]emby.EmbyMixInfo)

+ 1 - 2
internal/logic/series_helper/seriesHelper.go

@@ -18,7 +18,6 @@ import (
 	"github.com/allanpk716/ChineseSubFinder/internal/types/supplier"
 	"github.com/jinzhu/now"
 	"io/ioutil"
-	"path"
 	"path/filepath"
 	"strconv"
 	"strings"
@@ -209,7 +208,7 @@ func GetSeriesList(dir string) ([]string, error) {
 			}
 			continue
 		}
-		fullPath := path.Join(dir, curFile.Name())
+		fullPath := filepath.Join(dir, curFile.Name())
 		seriesDirList = append(seriesDirList, fullPath)
 	}
 

+ 10 - 10
internal/logic/sub_parser/ass/ass_test.go

@@ -25,17 +25,17 @@ func TestParser_DetermineFileTypeFromFile(t *testing.T) {
 		wantErr  bool
 		wantLang types.Language
 	}{
-		{name: "1", args: args{filePath: path.Join(testRootDir, "[xunlei]_0_C3A5CUsers5CAdministrator5CDesktop5CThe Boss Baby Family Business_S0E0.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
-		{name: "2", args: args{filePath: path.Join(testRootDir, "Loki - S01E01 - Glorious Purpose WEBDL-1080p Proper.chs[subhd].ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
-		{name: "3", args: args{filePath: path.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.简体&英文.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
-		{name: "4", args: args{filePath: path.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.繁体&英文.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseTraditionalEnglish},
-		{name: "5", args: args{filePath: path.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.繁体.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseTraditional},
+		{name: "1", args: args{filePath: filepath.Join(testRootDir, "[xunlei]_0_C3A5CUsers5CAdministrator5CDesktop5CThe Boss Baby Family Business_S0E0.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "2", args: args{filePath: filepath.Join(testRootDir, "Loki - S01E01 - Glorious Purpose WEBDL-1080p Proper.chs[subhd].ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "3", args: args{filePath: filepath.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.简体&英文.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "4", args: args{filePath: filepath.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.繁体&英文.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseTraditionalEnglish},
+		{name: "5", args: args{filePath: filepath.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.繁体.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseTraditional},
 		// 特殊一点的字幕
-		{name: "6", args: args{filePath: path.Join(testRootDir, "SP-Antebellum.1080p.WEB-DL.DD5.1.H.264-EVO.zh.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
-		{name: "7", args: args{filePath: path.Join(testRootDir, "SP-Gunpowder.Milkshake.2021.1080p.WEB.h264-RUMOUR[rarbg].chinese(简).ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
-		{name: "8", args: args{filePath: path.Join(testRootDir, "SP-One.Hundred.And.One.Dalmatians.1961.1080p.BluRay.x264.AAC5.1-[YTS.LT].zh-cn.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
-		{name: "9", args: args{filePath: path.Join(testRootDir, "SP-Pirates.of.the.Caribbean.The.Curse.of.the.Black.Pearl.2003.BluRay.1080p.x265.10bit.2Audio.MNHD-FRDS.zh-cn.ssa")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
-		{name: "10", args: args{filePath: path.Join(testRootDir, "SP-Schindlers.List.1993.BluRay.1080p.x265.10bit.2Audio.MNHD-FRDS.zh-cn.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "6", args: args{filePath: filepath.Join(testRootDir, "SP-Antebellum.1080p.WEB-DL.DD5.1.H.264-EVO.zh.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "7", args: args{filePath: filepath.Join(testRootDir, "SP-Gunpowder.Milkshake.2021.1080p.WEB.h264-RUMOUR[rarbg].chinese(简).ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "8", args: args{filePath: filepath.Join(testRootDir, "SP-One.Hundred.And.One.Dalmatians.1961.1080p.BluRay.x264.AAC5.1-[YTS.LT].zh-cn.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "9", args: args{filePath: filepath.Join(testRootDir, "SP-Pirates.of.the.Caribbean.The.Curse.of.the.Black.Pearl.2003.BluRay.1080p.x265.10bit.2Audio.MNHD-FRDS.zh-cn.ssa")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "10", args: args{filePath: filepath.Join(testRootDir, "SP-Schindlers.List.1993.BluRay.1080p.x265.10bit.2Audio.MNHD-FRDS.zh-cn.ass")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {

+ 4 - 4
internal/logic/sub_parser/srt/srt_test.go

@@ -24,12 +24,12 @@ func TestParser_DetermineFileType(t *testing.T) {
 		wantErr  bool
 		wantLang types.Language
 	}{
-		{name: "1", args: args{filePath: path.Join(testRootDir, "[zimuku]_5_Loki.S01E02.The.Variant.1080p.DSNP.WEB-DL.DDP5.1.Atmos.H.264-CM.chs&eng.srt")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
-		{name: "2", args: args{filePath: path.Join(testRootDir, "[zimuku]_5_Loki.S01E03.Lamentis.1080p.DSNP.WEB-DL.DDP5.1.H.264-TOMMY.chs&eng.srt")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
-		{name: "3", args: args{filePath: path.Join(testRootDir, "Bridge of Spies (2015) (1080p BluRay x265 Silence).zh-cn.srt")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "1", args: args{filePath: filepath.Join(testRootDir, "[zimuku]_5_Loki.S01E02.The.Variant.1080p.DSNP.WEB-DL.DDP5.1.Atmos.H.264-CM.chs&eng.srt")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "2", args: args{filePath: filepath.Join(testRootDir, "[zimuku]_5_Loki.S01E03.Lamentis.1080p.DSNP.WEB-DL.DDP5.1.H.264-TOMMY.chs&eng.srt")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
+		{name: "3", args: args{filePath: filepath.Join(testRootDir, "Bridge of Spies (2015) (1080p BluRay x265 Silence).zh-cn.srt")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimpleEnglish},
 		// 特殊一点的字幕
 		// 这一个不确定是什么类型的字幕
-		//{name: "4", args: args{filePath: path.Join(testRootDir, "SP-Empire.Of.Dreams.The.Story.Of.The.Star.Wars.Trilogy.2004.1080p.BluRay.x264.AAC5.1-[YTS.MX].zh-cn.srt")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimple},
+		//{name: "4", args: args{filePath: filepath.Join(testRootDir, "SP-Empire.Of.Dreams.The.Story.Of.The.Star.Wars.Trilogy.2004.1080p.BluRay.x264.AAC5.1-[YTS.MX].zh-cn.srt")}, wantNil: false, wantErr: false, wantLang: types.ChineseSimple},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {

+ 1 - 1
internal/logic/sub_supplier/subhd/subhd.go

@@ -644,7 +644,7 @@ search:
 		//截圖保存
 		nowProcessRoot, err := pkg.GetDebugFolder()
 		if err == nil {
-			page.MustScreenshot(path.Join(nowProcessRoot, "result.png"))
+			page.MustScreenshot(filepath.Join(nowProcessRoot, "result.png"))
 		} else {
 			s.log.Errorln("model.GetDebugFolder", err)
 		}

+ 7 - 7
internal/logic/sub_timeline_fixer/sub_timeline_fixer_helper.go

@@ -138,7 +138,7 @@ func (s SubTimelineFixerHelper) fixOneVideoSub(videoId string, videoRootPath str
 		}
 		for _, info := range subFixInfos {
 			// 写入 fix 后的字幕文件覆盖之前的字幕文件
-			desFixedSubFullName := path.Join(videoRootPath, subNewName)
+			desFixedSubFullName := filepath.Join(videoRootPath, subNewName)
 			err = s.saveSubFile(desFixedSubFullName, info.FixContent)
 			if err != nil {
 				return err
@@ -184,7 +184,7 @@ func (s SubTimelineFixerHelper) fixSubTimeline(enSubFile emby.SubInfo, ch_enSubF
 	//infoSrcNameWithOutExt := strings.Replace(infoSrc.Name, path.Ext(infoSrc.Name), "", -1)
 
 	// 把原始的文件缓存下来,新建缓存的文件夹
-	cacheTmpPath := path.Join(tmpSubFixCacheFolder, infoBaseNameWithOutExt)
+	cacheTmpPath := filepath.Join(tmpSubFixCacheFolder, infoBaseNameWithOutExt)
 	if pkg.IsDir(cacheTmpPath) == false {
 		err = os.MkdirAll(cacheTmpPath, os.ModePerm)
 		if err != nil {
@@ -192,15 +192,15 @@ func (s SubTimelineFixerHelper) fixSubTimeline(enSubFile emby.SubInfo, ch_enSubF
 		}
 	}
 	// 写入内置字幕、外置字幕原始文件
-	err = s.saveSubFile(path.Join(cacheTmpPath, infoBaseNameWithOutExt+".chinese(inside)"+infoBase.Ext), infoBase.Content)
+	err = s.saveSubFile(filepath.Join(cacheTmpPath, infoBaseNameWithOutExt+".chinese(inside)"+infoBase.Ext), infoBase.Content)
 	if err != nil {
 		return false, nil, fixedSubName, err
 	}
-	err = s.saveSubFile(path.Join(cacheTmpPath, infoSrc.Name), infoSrc.Content)
+	err = s.saveSubFile(filepath.Join(cacheTmpPath, infoSrc.Name), infoSrc.Content)
 	if err != nil {
 		return false, nil, fixedSubName, err
 	}
-	bok, offsetTime, sd, err := s.subTimelineFixer.GetOffsetTime(infoBase, infoSrc, path.Join(cacheTmpPath, infoSrc.Name+"-bar.html"), path.Join(cacheTmpPath, infoSrc.Name+".log"))
+	bok, offsetTime, sd, err := s.subTimelineFixer.GetOffsetTime(infoBase, infoSrc, filepath.Join(cacheTmpPath, infoSrc.Name+"-bar.html"), filepath.Join(cacheTmpPath, infoSrc.Name+".log"))
 	if offsetTime != 0 {
 		log_helper.GetLogger().Debugln(infoSrc.Name, "offset time is", fmt.Sprintf("%f", offsetTime), "s")
 	}
@@ -240,11 +240,11 @@ func (s SubTimelineFixerHelper) fixSubTimeline(enSubFile emby.SubInfo, ch_enSubF
 		desFixSubFileFullPath := ""
 		if hasDefault == true {
 			fixedSubName = subNewNameDefault
-			desFixSubFileFullPath = path.Join(cacheTmpPath, subNewNameDefault)
+			desFixSubFileFullPath = filepath.Join(cacheTmpPath, subNewNameDefault)
 
 		} else {
 			fixedSubName = subNewName
-			desFixSubFileFullPath = path.Join(cacheTmpPath, subNewName)
+			desFixSubFileFullPath = filepath.Join(cacheTmpPath, subNewName)
 		}
 		fixContent, err := s.subTimelineFixer.FixSubTimeline(infoSrc, offsetTime, desFixSubFileFullPath)
 		if err != nil {

+ 2 - 3
internal/pkg/archive_helper/unarchiveFile.go

@@ -12,7 +12,6 @@ import (
 	"golang.org/x/text/transform"
 	"io"
 	"io/ioutil"
-	"path"
 	"path/filepath"
 	"strings"
 )
@@ -126,7 +125,7 @@ func processOneFile(f archiver.File, notUTF8 bool, desRootPath string) error {
 		//读取到最终的缓冲区中
 		chunk = append(chunk, buf[:n]...)
 	}
-	err := utils.OutputFile(path.Join(desRootPath, decodeName), chunk)
+	err := utils.OutputFile(filepath.Join(desRootPath, decodeName), chunk)
 	if err != nil {
 		return err
 	}
@@ -164,7 +163,7 @@ func un7zOneFile(file *sevenzip.File, desRootPath string) error {
 	}
 	decodeName := file.Name
 	decodeName = filepath.Base(decodeName)
-	err = utils.OutputFile(path.Join(desRootPath, decodeName), data)
+	err = utils.OutputFile(filepath.Join(desRootPath, decodeName), data)
 	if err != nil {
 		return err
 	}

+ 4 - 4
internal/pkg/archive_helper/unarchiveFile_test.go

@@ -22,16 +22,16 @@ func TestUnArchiveFile(t *testing.T) {
 }
 
 func tetUnArchive(t *testing.T, testRootDir string, missionName string) {
-	fileFPath := path.Join(testRootDir, missionName)
-	desPath := path.Join(testRootDir, strings.ReplaceAll(filepath.Ext(missionName), ".", ""))
+	fileFPath := filepath.Join(testRootDir, missionName)
+	desPath := filepath.Join(testRootDir, strings.ReplaceAll(filepath.Ext(missionName), ".", ""))
 	err := UnArchiveFile(fileFPath, desPath)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if pkg.IsFile(path.Join(desPath, subASS)) == false {
+	if pkg.IsFile(filepath.Join(desPath, subASS)) == false {
 		t.Fatal(missionName, " unArchive failed")
 	}
-	if pkg.IsFile(path.Join(desPath, subSRT)) == false {
+	if pkg.IsFile(filepath.Join(desPath, subSRT)) == false {
 		t.Fatal(missionName, " unArchive failed")
 	}
 }

+ 6 - 7
internal/pkg/decode/decode.go

@@ -9,7 +9,6 @@ import (
 	PTN "github.com/middelink/go-parse-torrent-name"
 	"io/ioutil"
 	"os"
-	"path"
 	"path/filepath"
 	"regexp"
 	"strconv"
@@ -118,17 +117,17 @@ func GetImdbInfo4Movie(movieFileFullPath string) (types.VideoIMDBInfo, error) {
 		upperName := strings.ToLower(fi.Name())
 		if upperName == MetadataMovieXml {
 			// 找 movie.xml
-			movieXmlFPath = path.Join(dirPth, fi.Name())
+			movieXmlFPath = filepath.Join(dirPth, fi.Name())
 			break
 		} else if upperName == movieNfoFileName {
 			// movieName.nfo 文件
-			movieNameNfoFPath = path.Join(dirPth, fi.Name())
+			movieNameNfoFPath = filepath.Join(dirPth, fi.Name())
 			break
 		} else {
 			// 找 *.nfo,很可能是 movie.nfo
 			ok := strings.HasSuffix(fi.Name(), suffixNameNfo)
 			if ok {
-				nfoFilePath = path.Join(dirPth, fi.Name())
+				nfoFilePath = filepath.Join(dirPth, fi.Name())
 			}
 		}
 	}
@@ -179,13 +178,13 @@ func GetImdbInfo4SeriesDir(seriesDir string) (types.VideoIMDBInfo, error) {
 		upperName := strings.ToUpper(fi.Name())
 		if upperName == strings.ToUpper(MetadateTVNfo) {
 			// 连续剧的 nfo 文件
-			nfoFilePath = path.Join(seriesDir, fi.Name())
+			nfoFilePath = filepath.Join(seriesDir, fi.Name())
 			break
 		} else {
 			// 找 *.nfo
 			ok := strings.HasSuffix(fi.Name(), suffixNameNfo)
 			if ok {
-				nfoFilePath = path.Join(seriesDir, fi.Name())
+				nfoFilePath = filepath.Join(seriesDir, fi.Name())
 			}
 		}
 	}
@@ -208,7 +207,7 @@ func GetImdbInfo4OneSeriesEpisode(oneEpFPath string) (types.VideoIMDBInfo, error
 	EpNfoFileName := filepath.Base(oneEpFPath)
 	EpNfoFileName = strings.ReplaceAll(EpNfoFileName, filepath.Ext(oneEpFPath), suffixNameNfo)
 	// 全路径
-	EpNfoFPath := path.Join(EPdir, EpNfoFileName)
+	EpNfoFPath := filepath.Join(EPdir, EpNfoFileName)
 	//
 	imdbInfo := types.VideoIMDBInfo{}
 	doc := etree.NewDocument()

+ 82 - 0
internal/pkg/ffmpeg_helper/ffmpeg_helper.go

@@ -0,0 +1,82 @@
+package ffmpeg_helper
+
+import (
+	"bytes"
+	"fmt"
+	"github.com/tidwall/gjson"
+	"os/exec"
+
+	"strings"
+)
+
+func GetSubTileIndexList(videoFileFullPath string) error {
+
+	const args = "-v error -show_format -show_streams -print_format json"
+	cmdArgs := strings.Fields(args)
+	cmdArgs = append(cmdArgs, videoFileFullPath)
+	cmd := exec.Command("ffprobe", cmdArgs...)
+	buf := bytes.NewBufferString("")
+	//指定输出位置
+	cmd.Stderr = buf
+	cmd.Stdout = buf
+	err := cmd.Start()
+	if err != nil {
+		return err
+	}
+	err = cmd.Wait()
+	if err != nil {
+		return err
+	}
+
+	// 将获取到的反馈 json 字符串进行解析
+	println(buf.String())
+
+	return nil
+	//buf := bytes.NewBuffer(nil)
+	//inFileName := "X:\\连续剧\\瑞克和莫蒂 (2013)\\Season 5\\Rick and Morty - S05E10 - Rickmurai Jack WEBRip-1080p.mkv"
+	//stream := ffmpeg.Input(inFileName).Output("-hide_banner").Filter("stream", "")
+	//
+	//println(stream.String())
+}
+
+func parseJsonString2GetAudioAndSubs(input string) error {
+
+	streamsValue := gjson.Get(input, "streams.#")
+	if streamsValue.Exists() == false {
+		return nil
+	}
+	for i := 0; i < int(streamsValue.Num); i++ {
+
+		oneIndex := gjson.Get(input, fmt.Sprintf("streams.%d.index", i))
+		oneCodec_name := gjson.Get(input, fmt.Sprintf("streams.%d.codec_name", i))
+		oneCodec_type := gjson.Get(input, fmt.Sprintf("streams.%d.codec_type", i))
+		oneLanguage := gjson.Get(input, fmt.Sprintf("streams.%d.tags.language", i))
+
+		// 任意一个字段不存在则跳过
+		if oneIndex.Exists() == false || oneCodec_name.Exists() == false ||
+			oneCodec_type.Exists() == false {
+			continue
+		}
+
+		// 这里需要区分是字幕还是音频
+		if oneCodec_type.String() != "subtitle" {
+			// 字幕
+			if oneLanguage.Exists() == false {
+				continue
+			}
+
+		} else if oneCodec_type.String() != "subtitle" {
+			// 音频
+
+		} else {
+			continue
+		}
+
+		// 不是字幕也跳过
+		if oneCodec_name.String() != "subrip" || oneCodec_type.String() != "subtitle" {
+			continue
+		}
+	}
+
+	return nil
+}

+ 52 - 0
internal/pkg/ffmpeg_helper/ffmpeg_helper_test.go

@@ -0,0 +1,52 @@
+package ffmpeg_helper
+
+import (
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"io/ioutil"
+	"path/filepath"
+	"testing"
+)
+
+func TestGetSubTileIndexList(t *testing.T) {
+	videoFile := "X:\\连续剧\\瑞克和莫蒂 (2013)\\Season 5\\Rick and Morty - S05E10 - Rickmurai Jack WEBRip-1080p.mkv"
+
+	err := GetSubTileIndexList(videoFile)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func Test_parseJsonString2GetAudioAndSubs(t *testing.T) {
+
+	testDataPath := "../../../TestData/ffmpeg"
+	testRootDir, err := pkg.CopyTestData(testDataPath)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	type args struct {
+		input string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{name: "R&M S05E10", args: args{input: readString(filepath.Join(testRootDir, "R&M S05E10-video_stream.json"))}, wantErr: false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := parseJsonString2GetAudioAndSubs(tt.args.input); (err != nil) != tt.wantErr {
+				t.Errorf("parseJsonString2GetAudioAndSubs() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func readString(filePath string) string {
+	bytes, err := ioutil.ReadFile(filePath)
+	if err != nil {
+		return ""
+	}
+	return string(bytes)
+}

+ 2 - 2
internal/pkg/hot_fix/hot_fix_001_test.go

@@ -23,8 +23,8 @@ func TestHotFix001_Process(t *testing.T) {
 		t.Fatal(err)
 	}
 	// 测试文件夹
-	testMovieDir := path.Join(testRootDir, movieDir)
-	testSeriesDir := path.Join(testRootDir, seriesDir)
+	testMovieDir := filepath.Join(testRootDir, movieDir)
+	testSeriesDir := filepath.Join(testRootDir, seriesDir)
 	// 开始修复
 	hf001 := NewHotFix001(testMovieDir, testSeriesDir)
 	outData, err := hf001.Process()

+ 2 - 2
internal/pkg/hot_fix/hot_fix_hub_test.go

@@ -24,8 +24,8 @@ func TestHotFixProcess(t *testing.T) {
 		t.Fatal(err)
 	}
 	// 测试文件夹
-	testMovieDir := path.Join(testRootDir, movieDir)
-	testSeriesDir := path.Join(testRootDir, seriesDir)
+	testMovieDir := filepath.Join(testRootDir, movieDir)
+	testSeriesDir := filepath.Join(testRootDir, seriesDir)
 	// 开始修复
 	err = HotFixProcess(types.HotFixParam{
 		MovieRootDir:  testMovieDir,

+ 4 - 4
internal/pkg/log_helper/loghelper.go

@@ -6,7 +6,7 @@ import (
 	easy "github.com/t-tomalak/logrus-easy-formatter"
 	"io"
 	"os"
-	"path"
+	"path/filepath"
 	"sync"
 	"time"
 )
@@ -25,11 +25,11 @@ func NewLogHelper(appName string, level logrus.Level, maxAge time.Duration, rota
 	if err != nil {
 		panic(err)
 	}
-	pathRoot := path.Join(nowpath, "Logs")
-	fileAbsPath := path.Join(pathRoot, appName+".log")
+	pathRoot := filepath.Join(nowpath, "Logs")
+	fileAbsPath := filepath.Join(pathRoot, appName+".log")
 	// 下面配置日志每隔 X 分钟轮转一个新文件,保留最近 X 分钟的日志文件,多余的自动清理掉。
 	writer, _ := rotatelogs.New(
-		path.Join(pathRoot, appName+"--%Y%m%d%H%M--.log"),
+		filepath.Join(pathRoot, appName+"--%Y%m%d%H%M--.log"),
 		rotatelogs.WithLinkName(fileAbsPath),
 		rotatelogs.WithMaxAge(maxAge),
 		rotatelogs.WithRotationTime(rotationTime),

+ 4 - 5
internal/pkg/rod_helper/rodHelper.go

@@ -12,7 +12,6 @@ import (
 	"github.com/go-rod/rod/lib/proto"
 	"github.com/mholt/archiver/v3"
 	"os"
-	"path"
 	"path/filepath"
 	"sync"
 	"time"
@@ -164,15 +163,15 @@ func newPage(browser *rod.Browser) (*rod.Page, error) {
 func releaseAdblock() (string, error) {
 
 	adblockFolderPath := filepath.Join(os.TempDir(), "chinesesubfinder")
-	err := os.MkdirAll(path.Join(adblockFolderPath), os.ModePerm)
+	err := os.MkdirAll(filepath.Join(adblockFolderPath), os.ModePerm)
 	if err != nil {
 		return "", err
 	}
-	desPath := path.Join(adblockFolderPath, "RunAdblock")
+	desPath := filepath.Join(adblockFolderPath, "RunAdblock")
 	// 清理之前缓存的信息
 	_ = pkg.ClearFolder(desPath)
 	// 具体把 adblock zip 解压下载到哪里
-	outZipFileFPath := path.Join(adblockFolderPath, "adblock.zip")
+	outZipFileFPath := filepath.Join(adblockFolderPath, "adblock.zip")
 	adblockZipFile, err := os.Create(outZipFileFPath)
 	if err != nil {
 		return "", err
@@ -191,7 +190,7 @@ func releaseAdblock() (string, error) {
 	if err != nil {
 		return "", err
 	}
-	return path.Join(desPath, adblockInsideName), err
+	return filepath.Join(desPath, adblockInsideName), err
 }
 
 const adblockInsideName = "adblock"

+ 56 - 56
internal/pkg/sub_formatter/sub_format_changer_test.go

@@ -20,18 +20,18 @@ func TestSubFormatChanger_AutoDetectThenChangeTo(t *testing.T) {
 	series_name := "Loki"
 
 	// Emby 的信息
-	movieDir_org_emby := path.Join(testRootDir, "movie_org_emby")
-	seriesDir_org_emby := path.Join(testRootDir, "series_org_emby")
-	movieOneDir_org_emby := path.Join(movieDir_org_emby, movie_name)
-	seriesOneDir_org_emby := path.Join(seriesDir_org_emby, series_name, "Season 1")
+	movieDir_org_emby := filepath.Join(testRootDir, "movie_org_emby")
+	seriesDir_org_emby := filepath.Join(testRootDir, "series_org_emby")
+	movieOneDir_org_emby := filepath.Join(movieDir_org_emby, movie_name)
+	seriesOneDir_org_emby := filepath.Join(seriesDir_org_emby, series_name, "Season 1")
 	// Normal 的信息
-	movieDir_org_normal := path.Join(testRootDir, "movie_org_normal")
-	seriesDir_org_normal := path.Join(testRootDir, "series_org_normal")
-	movieOneDir_org_normal := path.Join(movieDir_org_normal, movie_name)
-	seriesOneDir_org_normal := path.Join(seriesDir_org_normal, series_name, "Season 1")
+	movieDir_org_normal := filepath.Join(testRootDir, "movie_org_normal")
+	seriesDir_org_normal := filepath.Join(testRootDir, "series_org_normal")
+	movieOneDir_org_normal := filepath.Join(movieDir_org_normal, movie_name)
+	seriesOneDir_org_normal := filepath.Join(seriesDir_org_normal, series_name, "Season 1")
 	// emby 转 emby 理论上不应该改文件
-	movieDir_emby_2_emby := path.Join(testRootDir, "movie_emby_2_emby")
-	seriesDir_emby_2_emby := path.Join(testRootDir, "series_emby_2_emby")
+	movieDir_emby_2_emby := filepath.Join(testRootDir, "movie_emby_2_emby")
+	seriesDir_emby_2_emby := filepath.Join(testRootDir, "series_emby_2_emby")
 
 	type fields struct {
 		movieRootDir  string
@@ -52,12 +52,12 @@ func TestSubFormatChanger_AutoDetectThenChangeTo(t *testing.T) {
 			args:   args{desFormatter: common.Normal},
 			want: RenameResults{
 				RenamedFiles: map[string]int{
-					path.Join(movieOneDir_org_emby, "AAA.zh.ass"):                    2,
-					path.Join(movieOneDir_org_emby, "AAA.zh.default.ass"):            1,
-					path.Join(movieOneDir_org_emby, "AAA.zh.srt"):                    1,
-					path.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.ass"):         5,
-					path.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.default.ass"): 1,
-					path.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.srt"):         1,
+					filepath.Join(movieOneDir_org_emby, "AAA.zh.ass"):                    2,
+					filepath.Join(movieOneDir_org_emby, "AAA.zh.default.ass"):            1,
+					filepath.Join(movieOneDir_org_emby, "AAA.zh.srt"):                    1,
+					filepath.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.ass"):         5,
+					filepath.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.default.ass"): 1,
+					filepath.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.srt"):         1,
 				},
 			}, wantErr: false},
 		{name: "normal 2 emby",
@@ -65,12 +65,12 @@ func TestSubFormatChanger_AutoDetectThenChangeTo(t *testing.T) {
 			args:   args{desFormatter: common.Emby},
 			want: RenameResults{
 				RenamedFiles: map[string]int{
-					path.Join(movieOneDir_org_normal, "AAA.chinese(简英).ass"):                    1,
-					path.Join(movieOneDir_org_normal, "AAA.chinese(简英).default.ass"):            1,
-					path.Join(movieOneDir_org_normal, "AAA.chinese(简英).srt"):                    1,
-					path.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(繁英).ass"):         1,
-					path.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(简英).default.ass"): 1,
-					path.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(简英).srt"):         1,
+					filepath.Join(movieOneDir_org_normal, "AAA.chinese(简英).ass"):                    1,
+					filepath.Join(movieOneDir_org_normal, "AAA.chinese(简英).default.ass"):            1,
+					filepath.Join(movieOneDir_org_normal, "AAA.chinese(简英).srt"):                    1,
+					filepath.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(繁英).ass"):         1,
+					filepath.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(简英).default.ass"): 1,
+					filepath.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(简英).srt"):         1,
 				},
 			}, wantErr: false},
 		{name: "emby 2 emby",
@@ -123,18 +123,18 @@ func TestSubFormatChangerProcess(t *testing.T) {
 	series_name := "Loki"
 
 	// Emby 的信息
-	movieDir_org_emby := path.Join(testRootDir, "movie_org_emby")
-	seriesDir_org_emby := path.Join(testRootDir, "series_org_emby")
-	movieOneDir_org_emby := path.Join(movieDir_org_emby, movie_name)
-	seriesOneDir_org_emby := path.Join(seriesDir_org_emby, series_name, "Season 1")
+	movieDir_org_emby := filepath.Join(testRootDir, "movie_org_emby")
+	seriesDir_org_emby := filepath.Join(testRootDir, "series_org_emby")
+	movieOneDir_org_emby := filepath.Join(movieDir_org_emby, movie_name)
+	seriesOneDir_org_emby := filepath.Join(seriesDir_org_emby, series_name, "Season 1")
 	// Normal 的信息
-	movieDir_org_normal := path.Join(testRootDir, "movie_org_normal")
-	seriesDir_org_normal := path.Join(testRootDir, "series_org_normal")
-	movieOneDir_org_normal := path.Join(movieDir_org_normal, movie_name)
-	seriesOneDir_org_normal := path.Join(seriesDir_org_normal, series_name, "Season 1")
+	movieDir_org_normal := filepath.Join(testRootDir, "movie_org_normal")
+	seriesDir_org_normal := filepath.Join(testRootDir, "series_org_normal")
+	movieOneDir_org_normal := filepath.Join(movieDir_org_normal, movie_name)
+	seriesOneDir_org_normal := filepath.Join(seriesDir_org_normal, series_name, "Season 1")
 	// emby 转 emby 理论上不应该改文件
-	movieDir_emby_2_emby := path.Join(testRootDir, "movie_emby_2_emby")
-	seriesDir_emby_2_emby := path.Join(testRootDir, "series_emby_2_emby")
+	movieDir_emby_2_emby := filepath.Join(testRootDir, "movie_emby_2_emby")
+	seriesDir_emby_2_emby := filepath.Join(testRootDir, "series_emby_2_emby")
 
 	type args struct {
 		movieRootDir    string
@@ -152,12 +152,12 @@ func TestSubFormatChangerProcess(t *testing.T) {
 			args: args{movieRootDir: movieDir_org_emby, seriesRootDir: seriesDir_org_emby, nowDesFormatter: common.Normal},
 			want: RenameResults{
 				RenamedFiles: map[string]int{
-					path.Join(movieOneDir_org_emby, "AAA.zh.ass"):                    2,
-					path.Join(movieOneDir_org_emby, "AAA.zh.default.ass"):            1,
-					path.Join(movieOneDir_org_emby, "AAA.zh.srt"):                    1,
-					path.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.ass"):         5,
-					path.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.default.ass"): 1,
-					path.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.srt"):         1,
+					filepath.Join(movieOneDir_org_emby, "AAA.zh.ass"):                    2,
+					filepath.Join(movieOneDir_org_emby, "AAA.zh.default.ass"):            1,
+					filepath.Join(movieOneDir_org_emby, "AAA.zh.srt"):                    1,
+					filepath.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.ass"):         5,
+					filepath.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.default.ass"): 1,
+					filepath.Join(seriesOneDir_org_emby, "Loki - S01E01.zh.srt"):         1,
 				},
 			}, wantErr: false},
 		// 然后从上面一个测试用例的文件夹中,继续,转 normal 2 emby
@@ -165,12 +165,12 @@ func TestSubFormatChangerProcess(t *testing.T) {
 			args: args{movieRootDir: movieDir_org_emby, seriesRootDir: movieDir_org_emby, nowDesFormatter: common.Emby},
 			want: RenameResults{
 				RenamedFiles: map[string]int{
-					path.Join(movieOneDir_org_emby, "AAA.chinese(简英).ass"):                    1,
-					path.Join(movieOneDir_org_emby, "AAA.chinese(简英).default.ass"):            1,
-					path.Join(movieOneDir_org_emby, "AAA.chinese(简英).srt"):                    1,
-					path.Join(seriesOneDir_org_emby, "Loki - S01E01.chinese(繁英).ass"):         1,
-					path.Join(seriesOneDir_org_emby, "Loki - S01E01.chinese(简英).default.ass"): 1,
-					path.Join(seriesOneDir_org_emby, "Loki - S01E01.chinese(简英).srt"):         1,
+					filepath.Join(movieOneDir_org_emby, "AAA.chinese(简英).ass"):                    1,
+					filepath.Join(movieOneDir_org_emby, "AAA.chinese(简英).default.ass"):            1,
+					filepath.Join(movieOneDir_org_emby, "AAA.chinese(简英).srt"):                    1,
+					filepath.Join(seriesOneDir_org_emby, "Loki - S01E01.chinese(繁英).ass"):         1,
+					filepath.Join(seriesOneDir_org_emby, "Loki - S01E01.chinese(简英).default.ass"): 1,
+					filepath.Join(seriesOneDir_org_emby, "Loki - S01E01.chinese(简英).srt"):         1,
 				},
 			}, wantErr: false},
 
@@ -184,12 +184,12 @@ func TestSubFormatChangerProcess(t *testing.T) {
 			args: args{movieRootDir: movieDir_org_normal, seriesRootDir: seriesDir_org_normal, nowDesFormatter: common.Emby},
 			want: RenameResults{
 				RenamedFiles: map[string]int{
-					path.Join(movieOneDir_org_normal, "AAA.chinese(简英).ass"):                    1,
-					path.Join(movieOneDir_org_normal, "AAA.chinese(简英).default.ass"):            1,
-					path.Join(movieOneDir_org_normal, "AAA.chinese(简英).srt"):                    1,
-					path.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(繁英).ass"):         1,
-					path.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(简英).default.ass"): 1,
-					path.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(简英).srt"):         1,
+					filepath.Join(movieOneDir_org_normal, "AAA.chinese(简英).ass"):                    1,
+					filepath.Join(movieOneDir_org_normal, "AAA.chinese(简英).default.ass"):            1,
+					filepath.Join(movieOneDir_org_normal, "AAA.chinese(简英).srt"):                    1,
+					filepath.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(繁英).ass"):         1,
+					filepath.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(简英).default.ass"): 1,
+					filepath.Join(seriesOneDir_org_normal, "Loki - S01E01.chinese(简英).srt"):         1,
 				},
 			}, wantErr: false},
 		// 然后从上面一个测试用例的文件夹中,继续,转 emby 2 normal
@@ -197,12 +197,12 @@ func TestSubFormatChangerProcess(t *testing.T) {
 			args: args{movieRootDir: movieDir_org_normal, seriesRootDir: seriesDir_org_normal, nowDesFormatter: common.Normal},
 			want: RenameResults{
 				RenamedFiles: map[string]int{
-					path.Join(movieOneDir_org_normal, "AAA.zh.ass"):                    1,
-					path.Join(movieOneDir_org_normal, "AAA.zh.default.ass"):            1,
-					path.Join(movieOneDir_org_normal, "AAA.zh.srt"):                    1,
-					path.Join(seriesOneDir_org_normal, "Loki - S01E01.zh.ass"):         1,
-					path.Join(seriesOneDir_org_normal, "Loki - S01E01.zh.default.ass"): 1,
-					path.Join(seriesOneDir_org_normal, "Loki - S01E01.zh.srt"):         1,
+					filepath.Join(movieOneDir_org_normal, "AAA.zh.ass"):                    1,
+					filepath.Join(movieOneDir_org_normal, "AAA.zh.default.ass"):            1,
+					filepath.Join(movieOneDir_org_normal, "AAA.zh.srt"):                    1,
+					filepath.Join(seriesOneDir_org_normal, "Loki - S01E01.zh.ass"):         1,
+					filepath.Join(seriesOneDir_org_normal, "Loki - S01E01.zh.default.ass"): 1,
+					filepath.Join(seriesOneDir_org_normal, "Loki - S01E01.zh.srt"):         1,
 				},
 			}, wantErr: false},
 	}

+ 1 - 1
internal/pkg/sub_helper/dialogue_merger_test.go

@@ -64,7 +64,7 @@ func TestNewDialogueMerger(t *testing.T) {
 	}
 
 	subParserHub := sub_parser_hub.NewSubParserHub(ass.NewParser(), srt.NewParser())
-	bFind, infoBase, err := subParserHub.DetermineFileTypeFromFile(path.Join(testRootDir, "2line-The Card Counter (2021) WEBDL-1080p.chinese(inside).ass"))
+	bFind, infoBase, err := subParserHub.DetermineFileTypeFromFile(filepath.Join(testRootDir, "2line-The Card Counter (2021) WEBDL-1080p.chinese(inside).ass"))
 	if err != nil {
 		t.Fatal(err)
 	}

+ 3 - 4
internal/pkg/sub_helper/sub_helper.go

@@ -14,7 +14,6 @@ import (
 	"github.com/go-rod/rod/lib/utils"
 	"io/ioutil"
 	"os"
-	"path"
 	"path/filepath"
 	"regexp"
 	"strconv"
@@ -40,7 +39,7 @@ func OrganizeDlSubFiles(tmpFolderName string, subInfos []supplier.SubInfo) (map[
 	// 基于以上两点,写了一堆啰嗦的逻辑···
 	for i := range subInfos {
 		// 先存下来,保存是时候需要前缀,前缀就是从那个网站下载来的
-		nowFileSaveFullPath := path.Join(tmpFolderFullPath, GetFrontNameAndOrgName(&subInfos[i]))
+		nowFileSaveFullPath := filepath.Join(tmpFolderFullPath, GetFrontNameAndOrgName(&subInfos[i]))
 		err = utils.OutputFile(nowFileSaveFullPath, subInfos[i].Data)
 		if err != nil {
 			log_helper.GetLogger().Errorln("getFrontNameAndOrgName - OutputFile", subInfos[i].FromWhere, subInfos[i].Name, subInfos[i].TopN, err)
@@ -63,7 +62,7 @@ func OrganizeDlSubFiles(tmpFolderName string, subInfos []supplier.SubInfo) (map[
 		} else {
 			// 那么就是需要解压的文件了
 			// 解压,给一个单独的文件夹
-			unzipTmpFolder := path.Join(tmpFolderFullPath, subInfos[i].FromWhere)
+			unzipTmpFolder := filepath.Join(tmpFolderFullPath, subInfos[i].FromWhere)
 			err = os.MkdirAll(unzipTmpFolder, os.ModePerm)
 			if err != nil {
 				return nil, err
@@ -83,7 +82,7 @@ func OrganizeDlSubFiles(tmpFolderName string, subInfos []supplier.SubInfo) (map[
 			// 这里需要给这些下载到的文件进行改名,加是从那个网站来的前缀,后续好查找
 			for _, fileFullPath := range subFileFullPaths {
 				newSubName := AddFrontName(subInfos[i], filepath.Base(fileFullPath))
-				newSubNameFullPath := path.Join(tmpFolderFullPath, newSubName)
+				newSubNameFullPath := filepath.Join(tmpFolderFullPath, newSubName)
 				// 改名
 				err = os.Rename(fileFullPath, newSubNameFullPath)
 				if err != nil {

+ 1 - 1
internal/pkg/sub_helper/sub_helper_test.go

@@ -17,7 +17,7 @@ func TestDeleteOneSeasonSubCacheFolder(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	if pkg.IsDir(path.Join(testRootDir, "Sub_S1E0")) == true {
+	if pkg.IsDir(filepath.Join(testRootDir, "Sub_S1E0")) == true {
 		t.Fatal("Sub_S1E0 not delete")
 	}
 }

+ 7 - 7
internal/pkg/sub_parser_hub/subParserHub_test.go

@@ -24,13 +24,13 @@ func TestSubParserHub_IsSubHasChinese(t *testing.T) {
 		args args
 		want bool
 	}{
-		{name: "1", args: args{filePath: path.Join(testRootDir, "[xunlei]_0_C3A5CUsers5CAdministrator5CDesktop5CThe Boss Baby Family Business_S0E0.ass")}, want: true},
-		{name: "2", args: args{filePath: path.Join(testRootDir, "Loki - S01E01 - Glorious Purpose WEBDL-1080p Proper.chs[subhd].ass")}, want: true},
-		{name: "3", args: args{filePath: path.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.简体&英文.ass")}, want: true},
-		{name: "4", args: args{filePath: path.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.繁体&英文.ass")}, want: true},
-		{name: "5", args: args{filePath: path.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.繁体.ass")}, want: true},
-		{name: "6", args: args{filePath: path.Join(testRootDir, "[zimuku]_5_Loki.S01E02.The.Variant.1080p.DSNP.WEB-DL.DDP5.1.Atmos.H.264-CM.chs&eng.srt")}, want: true},
-		{name: "7", args: args{filePath: path.Join(testRootDir, "[zimuku]_5_Loki.S01E03.Lamentis.1080p.DSNP.WEB-DL.DDP5.1.H.264-TOMMY.chs&eng.srt")}, want: true},
+		{name: "1", args: args{filePath: filepath.Join(testRootDir, "[xunlei]_0_C3A5CUsers5CAdministrator5CDesktop5CThe Boss Baby Family Business_S0E0.ass")}, want: true},
+		{name: "2", args: args{filePath: filepath.Join(testRootDir, "Loki - S01E01 - Glorious Purpose WEBDL-1080p Proper.chs[subhd].ass")}, want: true},
+		{name: "3", args: args{filePath: filepath.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.简体&英文.ass")}, want: true},
+		{name: "4", args: args{filePath: filepath.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.繁体&英文.ass")}, want: true},
+		{name: "5", args: args{filePath: filepath.Join(testRootDir, "oslo.2021.1080p.web.h264-naisu.繁体.ass")}, want: true},
+		{name: "6", args: args{filePath: filepath.Join(testRootDir, "[zimuku]_5_Loki.S01E02.The.Variant.1080p.DSNP.WEB-DL.DDP5.1.Atmos.H.264-CM.chs&eng.srt")}, want: true},
+		{name: "7", args: args{filePath: filepath.Join(testRootDir, "[zimuku]_5_Loki.S01E03.Lamentis.1080p.DSNP.WEB-DL.DDP5.1.H.264-TOMMY.chs&eng.srt")}, want: true},
 	}
 
 	subParserHub := NewSubParserHub(ass.NewParser(), srt.NewParser())

+ 71 - 72
internal/pkg/sub_timeline_fixer/fixer_test.go

@@ -11,7 +11,6 @@ import (
 	"github.com/james-bowman/nlp"
 	"github.com/james-bowman/nlp/measures/pairwise"
 	"gonum.org/v1/gonum/mat"
-	"path"
 	"path/filepath"
 	"strings"
 	"testing"
@@ -27,7 +26,7 @@ func TestStopWordCounter(t *testing.T) {
 
 	subParserHub := sub_parser_hub.NewSubParserHub(ass.NewParser(), srt.NewParser())
 
-	bFind, info, err := subParserHub.DetermineFileTypeFromFile(path.Join(testRootDir, "R&M S05E10 - English.srt"))
+	bFind, info, err := subParserHub.DetermineFileTypeFromFile(filepath.Join(testRootDir, "R&M S05E10 - English.srt"))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -68,14 +67,14 @@ func TestGetOffsetTime(t *testing.T) {
 		/*
 			这里有几个比较理想的字幕时间轴校正的示例
 		*/
-		{name: "R&M S05E01", args: args{enSubFile: path.Join(testRootDirYes, "R&M S05E01 - English.srt"),
-			ch_enSubFile:           path.Join(testRootDirYes, "R&M S05E01 - 简英.srt"),
+		{name: "R&M S05E01", args: args{enSubFile: filepath.Join(testRootDirYes, "R&M S05E01 - English.srt"),
+			ch_enSubFile:           filepath.Join(testRootDirYes, "R&M S05E01 - 简英.srt"),
 			staticLineFileSavePath: "bar.html"}, want: -6.42981818181818, wantErr: false},
-		{name: "R&M S05E10", args: args{enSubFile: path.Join(testRootDirYes, "R&M S05E10 - English.ass"),
-			ch_enSubFile:           path.Join(testRootDirYes, "R&M S05E10 - 简英.ass"),
+		{name: "R&M S05E10", args: args{enSubFile: filepath.Join(testRootDirYes, "R&M S05E10 - English.ass"),
+			ch_enSubFile:           filepath.Join(testRootDirYes, "R&M S05E10 - 简英.ass"),
 			staticLineFileSavePath: "bar.html"}, want: -6.335985401459854, wantErr: false},
-		{name: "基地 S01E03", args: args{enSubFile: path.Join(testRootDirYes, "基地 S01E03 - English.ass"),
-			ch_enSubFile:           path.Join(testRootDirYes, "基地 S01E03 - 简英.ass"),
+		{name: "基地 S01E03", args: args{enSubFile: filepath.Join(testRootDirYes, "基地 S01E03 - English.ass"),
+			ch_enSubFile:           filepath.Join(testRootDirYes, "基地 S01E03 - 简英.ass"),
 			staticLineFileSavePath: "bar.html"}, want: -32.09061538461539, wantErr: false},
 		/*
 			WTF,这部剧集
@@ -83,190 +82,190 @@ func TestGetOffsetTime(t *testing.T) {
 			内置的英文字幕时间轴是歪的,所以修正完了就错了
 		*/
 		{name: "Dan Brown's The Lost Symbol - S01E01", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E01.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E01.chinese(简英,shooter).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E01.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E01.chinese(简英,shooter).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 1.3217821782178225, wantErr: false},
 		{name: "Dan Brown's The Lost Symbol - S01E02", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E02.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E02.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E02.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E02.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: -0.5253383458646617, wantErr: false},
 		{name: "Dan Brown's The Lost Symbol - S01E03", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E03.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E03.chinese(繁英,xunlei).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E03.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E03.chinese(繁英,xunlei).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: -0.505656, wantErr: false},
 		{name: "Dan Brown's The Lost Symbol - S01E04", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E04.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E04.chinese(简英,zimuku).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E04.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Dan Brown's The Lost Symbol - S01E04.chinese(简英,zimuku).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: -0.633415, wantErr: false},
 		/*
 			只有一个是字幕下载了一个错误的,其他的无需修正
 		*/
 		{name: "Don't Breathe 2 (2021) - shooter-srt", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(inside).srt"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(简英,shooter).srt"),
+			enSubFile:              filepath.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(inside).srt"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(简英,shooter).srt"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Don't Breathe 2 (2021) - subhd-srt error matched sub", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(inside).srt"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(简英,subhd).srt"),
+			enSubFile:              filepath.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(inside).srt"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(简英,subhd).srt"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Don't Breathe 2 (2021) - xunlei-ass", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(简英,xunlei).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(简英,xunlei).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Don't Breathe 2 (2021) - zimuku-ass", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(简英,zimuku).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Don't Breathe 2 (2021).chinese(简英,zimuku).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		/*
 			基地
 		*/
 		{name: "Foundation (2021) - S01E01", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Foundation (2021) - S01E01.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Foundation (2021) - S01E01.chinese(简英,zimuku).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Foundation (2021) - S01E01.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Foundation (2021) - S01E01.chinese(简英,zimuku).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Foundation (2021) - S01E02", args: args{
-			enSubFile:              path.Join(testRootDirYes, "Foundation (2021) - S01E02.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirYes, "Foundation (2021) - S01E02.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirYes, "Foundation (2021) - S01E02.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirYes, "Foundation (2021) - S01E02.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: -30.624840, wantErr: false},
 		{name: "Foundation (2021) - S01E03", args: args{
-			enSubFile:              path.Join(testRootDirYes, "Foundation (2021) - S01E03.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirYes, "Foundation (2021) - S01E03.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirYes, "Foundation (2021) - S01E03.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirYes, "Foundation (2021) - S01E03.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: -32.085037037037054, wantErr: false},
 		{name: "Foundation (2021) - S01E04", args: args{
-			enSubFile:              path.Join(testRootDirYes, "Foundation (2021) - S01E04.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirYes, "Foundation (2021) - S01E04.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirYes, "Foundation (2021) - S01E04.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirYes, "Foundation (2021) - S01E04.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: -36.885074, wantErr: false},
 		{name: "Foundation (2021) - S01E04", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Foundation (2021) - S01E04.chinese(inside).srt"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Foundation (2021) - S01E04.chinese(繁英,shooter).srt"),
+			enSubFile:              filepath.Join(testRootDirNo, "Foundation (2021) - S01E04.chinese(inside).srt"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Foundation (2021) - S01E04.chinese(繁英,shooter).srt"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		/*
 			The Card Counter
 		*/
 		{name: "The Card Counter", args: args{
-			enSubFile:              path.Join(testRootDirNo, "The Card Counter (2021).chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "The Card Counter (2021).chinese(简英,xunlei).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "The Card Counter (2021).chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "The Card Counter (2021).chinese(简英,xunlei).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "The Card Counter", args: args{
-			enSubFile:              path.Join(testRootDirNo, "The Card Counter (2021).chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "The Card Counter (2021).chinese(简英,shooter).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "The Card Counter (2021).chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "The Card Counter (2021).chinese(简英,shooter).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0.224844, wantErr: false},
 		/*
 			Kingdom Ashin of the North
 		*/
 		{name: "Kingdom Ashin of the North - error matched sub", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Kingdom Ashin of the North (2021).chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Kingdom Ashin of the North (2021).chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Kingdom Ashin of the North (2021).chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Kingdom Ashin of the North (2021).chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		/*
 			Only Murders in the Building
 		*/
 		{name: "Only Murders in the Building - S01E06", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Only Murders in the Building - S01E06.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Only Murders in the Building - S01E06.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Only Murders in the Building - S01E06.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Only Murders in the Building - S01E06.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Only Murders in the Building - S01E08", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Only Murders in the Building - S01E08.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Only Murders in the Building - S01E08.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Only Murders in the Building - S01E08.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Only Murders in the Building - S01E08.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		/*
 			Ted Lasso
 		*/
 		{name: "Ted Lasso - S02E09", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Ted Lasso - S02E09.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Ted Lasso - S02E09.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Ted Lasso - S02E09.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Ted Lasso - S02E09.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Ted Lasso - S02E09", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Ted Lasso - S02E09.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Ted Lasso - S02E09.chinese(简英,zimuku).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Ted Lasso - S02E09.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Ted Lasso - S02E09.chinese(简英,zimuku).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Ted Lasso - S02E10", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Ted Lasso - S02E10", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(简英,zimuku).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(简英,zimuku).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Ted Lasso - S02E10", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(简英,shooter).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Ted Lasso - S02E10.chinese(简英,shooter).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Ted Lasso - S02E11", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Ted Lasso - S02E11.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Ted Lasso - S02E11.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Ted Lasso - S02E11.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Ted Lasso - S02E11.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Ted Lasso - S02E11", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Ted Lasso - S02E11.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Ted Lasso - S02E11.chinese(简英,zimuku).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Ted Lasso - S02E11.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Ted Lasso - S02E11.chinese(简英,zimuku).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Ted Lasso - S02E12", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Ted Lasso - S02E12.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Ted Lasso - S02E12.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Ted Lasso - S02E12.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Ted Lasso - S02E12.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "Ted Lasso - S02E12", args: args{
-			enSubFile:              path.Join(testRootDirNo, "Ted Lasso - S02E12.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "Ted Lasso - S02E12.chinese(简英,shooter).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "Ted Lasso - S02E12.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "Ted Lasso - S02E12.chinese(简英,shooter).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		/*
 			The Protégé
 		*/
 		{name: "The Protégé", args: args{
-			enSubFile:              path.Join(testRootDirNo, "The Protégé (2021).chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "The Protégé (2021).chinese(简英,zimuku).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "The Protégé (2021).chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "The Protégé (2021).chinese(简英,zimuku).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "The Protégé", args: args{
-			enSubFile:              path.Join(testRootDirNo, "The Protégé (2021).chinese(inside).srt"),
-			ch_enSubFile:           path.Join(testRootDirNo, "The Protégé (2021).chinese(简英,shooter).srt"),
+			enSubFile:              filepath.Join(testRootDirNo, "The Protégé (2021).chinese(inside).srt"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "The Protégé (2021).chinese(简英,shooter).srt"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		/*
 			The Witcher Nightmare of the Wolf
 		*/
 		{name: "The Witcher Nightmare of the Wolf", args: args{
-			enSubFile:              path.Join(testRootDirNo, "The Witcher Nightmare of the Wolf.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "The Witcher Nightmare of the Wolf.chinese(简英,zimuku).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "The Witcher Nightmare of the Wolf.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "The Witcher Nightmare of the Wolf.chinese(简英,zimuku).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		/*
 			What If…!
 		*/
 		{name: "What If…! - S01E07", args: args{
-			enSubFile:              path.Join(testRootDirNo, "What If…! - S01E07.chinese(inside).ass"),
-			ch_enSubFile:           path.Join(testRootDirNo, "What If…! - S01E07.chinese(简英,subhd).ass"),
+			enSubFile:              filepath.Join(testRootDirNo, "What If…! - S01E07.chinese(inside).ass"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "What If…! - S01E07.chinese(简英,subhd).ass"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 		{name: "What If…! - S01E09", args: args{
-			enSubFile:              path.Join(testRootDirNo, "What If…! - S01E09.chinese(inside).srt"),
-			ch_enSubFile:           path.Join(testRootDirNo, "What If…! - S01E09.chinese(简英,shooter).srt"),
+			enSubFile:              filepath.Join(testRootDirNo, "What If…! - S01E09.chinese(inside).srt"),
+			ch_enSubFile:           filepath.Join(testRootDirNo, "What If…! - S01E09.chinese(简英,shooter).srt"),
 			staticLineFileSavePath: "bar.html"},
 			want: 0, wantErr: false},
 	}

+ 7 - 8
internal/pkg/util.go

@@ -12,7 +12,6 @@ import (
 	"net/http"
 	"os"
 	"os/exec"
-	"path"
 	"path/filepath"
 	"regexp"
 	"runtime"
@@ -105,7 +104,7 @@ func AddBaseUrl(baseUrl, url string) string {
 func GetDebugFolder() (string, error) {
 	if defDebugFolder == "" {
 		nowProcessRoot, _ := os.Getwd()
-		nowProcessRoot = path.Join(nowProcessRoot, common.DebugFolder)
+		nowProcessRoot = filepath.Join(nowProcessRoot, common.DebugFolder)
 		err := os.MkdirAll(nowProcessRoot, os.ModePerm)
 		if err != nil {
 			return "", err
@@ -120,7 +119,7 @@ func GetDebugFolder() (string, error) {
 func GetRootTmpFolder() (string, error) {
 	if defTmpFolder == "" {
 		nowProcessRoot, _ := os.Getwd()
-		nowProcessRoot = path.Join(nowProcessRoot, common.TmpFolder)
+		nowProcessRoot = filepath.Join(nowProcessRoot, common.TmpFolder)
 		err := os.MkdirAll(nowProcessRoot, os.ModePerm)
 		if err != nil {
 			return "", err
@@ -168,7 +167,7 @@ func GetTmpFolder(folderName string) (string, error) {
 	if err != nil {
 		return "", err
 	}
-	tmpFolderFullPath := path.Join(rootPath, folderName)
+	tmpFolderFullPath := filepath.Join(rootPath, folderName)
 	err = os.MkdirAll(tmpFolderFullPath, os.ModePerm)
 	if err != nil {
 		return "", err
@@ -345,8 +344,8 @@ func CopyDir(src string, dst string) error {
 		return err
 	}
 	for _, fd := range fds {
-		srcfp := path.Join(src, fd.Name())
-		dstfp := path.Join(dst, fd.Name())
+		srcfp := filepath.Join(src, fd.Name())
+		dstfp := filepath.Join(dst, fd.Name())
 
 		if fd.IsDir() {
 			if err = CopyDir(srcfp, dstfp); err != nil {
@@ -364,8 +363,8 @@ func CopyDir(src string, dst string) error {
 // CopyTestData 单元测试前把测试的数据 copy 一份出来操作,src 目录中默认应该有一个 org 原始数据文件夹,然后需要复制一份 test 文件夹出来
 func CopyTestData(srcDir string) (string, error) {
 	// 测试数据的文件夹
-	orgDir := path.Join(srcDir, "org")
-	testDir := path.Join(srcDir, "test")
+	orgDir := filepath.Join(srcDir, "org")
+	testDir := filepath.Join(srcDir, "test")
 
 	if IsDir(testDir) == true {
 		err := ClearFolder(testDir)