// 保存MP3
        public void Save(ExcelSheetModel[] sheetItems)
        {
            foreach (var item in sheetItems)
            {
                // 每个年份分类下一个文件夹, 每个年份下多个专辑
                // 每个专辑一个文件夹, 下面有唱词,MP3
                foreach (var mediaItem in item.MediaItems)
                {
                    // 年份 + 专辑名称

                    // MP3下载文件夹
                    var mp3DownloadDir = Path.Combine(
                        StaticVariables.GetDownloadDir(),
                        item.Name,
                        mediaItem.Title);
                    // MP4 文件单独放一个文件夹, 以后转换为MP3方便
                    var mp4DownloadDir = Path.Combine(
                        StaticVariables.GetDownloadDir(),
                        StaticVariables.MP4_FOLDER_NAME,
                        item.Name,
                        mediaItem.Title);

                    DownloadMediaItem(mp3DownloadDir, mp4DownloadDir, mediaItem);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// 有的MP3文件标题有错, 解析artists会出错
        /// 手动修改MP3Info.Title属性, 和已经下载好的MP3文件名
        ///
        /// 如
        /// "09. 四郎探母9(坐宫) 管绍华 王玉蓉 百代"
        /// 修改为
        /// "09.四郎探母9(坐宫) 管绍华 王玉蓉 百代"
        /// 否则原标题分组是 "09." "四郎探母9(坐宫)" "管绍华" "王玉蓉" "百代",
        /// 会把"四郎探母9(坐宫)"也当作artist
        /// </summary>
        private static void NormalizeMp3FileName(List <ExcelSheetModel> sheetModels, string oldFileName, string newFileName)
        {
            string  categoryName = null, albumName = null;
            Mp3Info wrongMp3 = null;

            // 大分类: 如 2018年出品-京剧
            foreach (var categoryInfo in sheetModels)
            {
                // 该分类下面的专辑: 1.京剧正宗谭派《王又宸专辑》
                foreach (MediaItem mediaItem in categoryInfo.MediaItems)
                {
                    wrongMp3 = mediaItem.Mp3Items?.FirstOrDefault(x => x.Title == oldFileName);
                    if (wrongMp3 != null)
                    {
                        categoryName = categoryInfo.Name;
                        albumName    = mediaItem.Title;
                        break;
                    }
                }

                if (wrongMp3 != null)
                {
                    break;
                }
            }

            if (wrongMp3 != null &&
                !string.IsNullOrEmpty(categoryName) &&
                !string.IsNullOrEmpty(albumName))
            {
                var mp3FilePath = System.IO.Path.Combine(StaticVariables.GetDownloadDir(),
                                                         categoryName, // "2018年出品-京剧",
                                                         albumName,    // "11 京剧红生大王《林树森专辑》",
                                                         oldFileName + ".mp3");

                var newMp3FilePath = System.IO.Path.Combine(
                    System.IO.Path.GetDirectoryName(mp3FilePath),
                    newFileName + ".mp3"
                    );
                if (System.IO.File.Exists(mp3FilePath))
                {
                    if (System.IO.File.Exists(newMp3FilePath))
                    {
                        System.IO.File.Delete(newMp3FilePath);
                    }

                    System.IO.File.Move(mp3FilePath, newMp3FilePath);
                }

                // 更新MP3标题
                wrongMp3.Title = newFileName;
            }
        }
        public void DownloadMp4Items(List <Mp4Item> mp4Items, bool deleteIfExist = false)
        {
            var mp4DownloadDIr = System.IO.Path.Combine(
                StaticVariables.GetDownloadDir(),
                StaticVariables.MP4_FOLDER_NAME);

            if (Directory.Exists(mp4DownloadDIr))
            {
                Directory.CreateDirectory(mp4DownloadDIr);
            }

            foreach (var categoryInfo in mp4Items.GroupBy(x => x.CategoryName))
            {
                var categoryName = categoryInfo.Key;
                foreach (var albumInfo in categoryInfo.GroupBy(x => x.AblumName))
                {
                    // albumInfo
                    var albumName     = albumInfo.Key;
                    var albumMp4Items = albumInfo.ToArray();
                    if (albumMp4Items.Length == 0)
                    {
                        continue;
                    }

                    // key: url, value: 保存地址
                    Dictionary <string, string> downloadItems = new Dictionary <string, string>();

                    foreach (var item in albumMp4Items)
                    {
                        if (string.IsNullOrEmpty(item.Mp4DownloadUrl))
                        {
                            HtmlParseLogger.Error($"{item.Mp3FileName} 没有下载地址,跳过");
                            continue;
                        }

                        var dir = Path.Combine(mp4DownloadDIr,
                                               categoryName,
                                               albumName);
                        if (!Directory.Exists(dir))
                        {
                            Directory.CreateDirectory(dir);
                        }

                        var mp3Name = Path.Combine(dir, $"{item.Mp3FileName}.mp4");
                        downloadItems.Add(item.Mp4DownloadUrl, mp3Name);
                    }

                    DownadFiles(albumName, downloadItems);
                }
                //OperaHtmlParser.Mp4Item
            }
        }
        public static void Save(string fileName, ExcelSheetModel[] sheetItems)
        {
            fileName = Path.Combine(StaticVariables.GetDownloadDir(), fileName);

            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                IWorkbook workbook = new XSSFWorkbook();

                foreach (var item in sheetItems)
                {
                    WriteToSheet(workbook, item);
                }

                workbook.Write(fs);

                _cachedStyle = null;
            }
        }
        public static void Save(ExcelSheetModel[] sheetItems)
        {
            #region 读取模板中样式

            // 默认新创建word没有Heading1,Heading2...这些样式,需要手动创建
            // 采用建一个word样式模板方法
            // 参考(第2个答案):
            // https://stackoverflow.com/questions/2643822/how-can-i-use-predefined-formats-in-docx-with-poi

            /*
             * XWPFDocument template = new XWPFDocument(new FileInputStream(new File("Template.dotx")));
             *
             * XWPFDocument doc = new XWPFDocument();
             * // let's copy styles from template to new doc
             * XWPFStyles newStyles = doc.createStyles();
             * newStyles.setStyles(template.getStyle());   // 复制模板样式到当前文件
             *
             * XWPFParagraph para = doc.createParagraph();
             * para.setStyle("Heading1");
             *
             * XWPFRun run = para.createRun();
             * run.setText("Heading 1");
             *
             * return doc;
             */

            NPOI.OpenXmlFormats.Wordprocessing.CT_Styles templateStyle = null;

            if (File.Exists("template.docx"))
            {
                using (var stream = new System.IO.FileStream("template.docx", System.IO.FileMode.Open))
                {
                    XWPFDocument doc = new XWPFDocument(stream);
                    templateStyle = doc.GetCTStyle();
                }
            }
            else
            {
                System.Console.WriteLine("模板文件不存在, 生成word样式会有问题!");
            }

            #endregion

            var downloadDir = StaticVariables.GetDownloadDir();

            if (!Directory.Exists(downloadDir))
            {
                Directory.CreateDirectory(downloadDir);
            }

            #region 每个专辑一个歌词文件

            /*
             * foreach (var item in sheetItems)
             * {
             *  // 每个专辑一个唱词文件
             *  foreach (var mediaItem in item.MediaItems)
             *  {
             *      var subDir = Path.Combine(downloadDir, item.Name, "唱词");
             *      if (!Directory.Exists(subDir))
             *      {
             *          Directory.CreateDirectory(subDir);
             *      }
             *
             *      var fileName = Path.Combine(subDir, mediaItem.Title + ".docx");
             *
             *      using (FileStream fs = new FileStream(fileName, FileMode.Create))
             *      {
             *          var doc = new XWPFDocument();
             *          doc.GetStyles().SetStyles(templateStyle);
             *
             *          WriteMedia(doc, mediaItem);
             *          doc.Write(fs);
             *      }
             *  }
             * }
             */
            #endregion

            #region 所有专辑合并成一个文件

            // 全部的歌词
            var allLyricDoc = new XWPFDocument();
            allLyricDoc.GetStyles().SetStyles(templateStyle);

            foreach (var item in sheetItems)
            {
                // TODO : 前面已经创建过文件
                var subDir = Path.Combine(downloadDir, item.Name);

                if (!Directory.Exists(subDir))
                {
                    Directory.CreateDirectory(subDir);
                }

                try
                {
                    // 每个分类(2018年出品-京剧, 2019年出品-京剧)一个歌词文件
                    var fileName = Path.Combine(subDir, "_所有唱词_" + item.Name + ".docx");

                    using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate))
                    {
                        var doc = new XWPFDocument();
                        doc.GetStyles().SetStyles(templateStyle);

                        // 当前分类下歌词
                        WriteToDoc(doc, item);

                        // 全部歌词
                        WriteToDoc(allLyricDoc, item);

                        doc.Write(fs);
                    }
                }
                catch (System.Exception)
                {
                    continue;
                }
            }

            // 保存全部歌词
            var allLyricFilePath = Path.Combine(downloadDir, "所有唱词.docx");
            using (FileStream fs = new FileStream(allLyricFilePath, FileMode.OpenOrCreate))
            {
                allLyricDoc.Write(fs);
            }
            #endregion
        }
        public static void GenerateTagInfo(ExcelSheetModel[] sheetModels)
        {
            if (sheetModels == null)
            {
                return;
            }

            #region 默认专辑封面名称为_avatar.jpg, 需要手动裁剪, 先根据下载来的图片_covert.jpg复制一个,编辑之后直接覆盖

            // 找出所有_cover.jpg
            var albumCovers = Directory.GetFiles(StaticVariables.GetDownloadDir(), StaticVariables.ALBUM_COVER_NAME, SearchOption.AllDirectories);
            foreach (var albumCoverFile in albumCovers)
            {
                var coverDir = Path.GetDirectoryName(albumCoverFile);

                // _avatar.jpg
                var mp3CoverFile = Path.Combine(coverDir, StaticVariables.ALBUM_MP3_COVER_NAME);

                // 如果存在则跳过
                if (File.Exists(mp3CoverFile))
                {
                    continue;
                }

                File.Copy(albumCoverFile, mp3CoverFile, true);
                System.Console.WriteLine("$复制专辑{Path.GetDirectoryName(coverDir)}封面");
            }

            #endregion

            // 大分类: 如 2018年出品-京剧
            foreach (var categoryInfo in sheetModels)
            {
                // 该分类下面的专辑: 1.京剧正宗谭派《王又宸专辑》
                foreach (MediaItem mediaItem in categoryInfo.MediaItems)
                {
                    System.Console.WriteLine($"专辑{mediaItem.Title}生成标签...");

                    foreach (var mp3Info in mediaItem.Mp3Items)
                    {
                        // 当前专辑文件夹
                        var mp3FileDir = Path.Combine(
                            StaticVariables.GetDownloadDir(),   // _downloads
                            categoryInfo.Name,                  // 2018年出品-京剧
                            mediaItem.Title                     // 1.京剧正宗谭派《王又宸专辑》
                            );

                        // mp3 地址
                        var mp3FilePath = Path.Combine(
                            mp3FileDir,
                            mp3Info.Title + ".mp3"              // 01.李陵碑1 王又宸 高亭.mp3
                            );

                        if (!System.IO.File.Exists(mp3FilePath))
                        {
                            HtmlParseLogger.TagError($"{mp3Info.Title}.mp3文件不存在, 跳过生成tag");
                            continue;
                        }
                        try
                        {
                            using (var fs = new FileStream(mp3FilePath, FileMode.Open))
                            {
                                var tagFile = TagLib.File.Create(
                                    new TagLib.StreamFileAbstraction(mp3FilePath, fs, fs));

                                var tags = tagFile.GetTag(TagLib.TagTypes.Id3v2);

                                // 设置标签属性
                                SetTags(tags, mp3FileDir, mp3Info, mediaItem);

                                tagFile.Save();
                            }
                        }
                        catch (System.Exception ex)
                        {
                            HtmlParseLogger.TagError($"生成{mp3Info.Title}.mp3 出错, {ex.Message}");
                            continue;
                        }
                    }
                }
            }
        }
Esempio n. 7
0
        static void Main(string[] args)
        {
            //var url2 = "http://www.bavc.com.cn/w10279097.htm?page=1";

            HtmlParseLogger.TagError("tag 错误");
            Uri uri    = new Uri("http://mpv.videocc.net/d69fff2eae/c/d69fff2eaef75ebc9d69ae4e5f3a891c_1.mp4?pid=1578623766586X1882197");
            var query  = uri.Query;
            var index  = uri.OriginalString.IndexOf(query);
            var newUrl = uri.OriginalString.Substring(0, index);

            System.Console.WriteLine(uri.OriginalString);
            System.Console.WriteLine(newUrl);


            HtmlParseLogger.Info("Start...");

            #region 从缓存文件 或 解析html读取信息

            // 要下载的目录
            Dictionary <string, string> downloadItems = new Dictionary <string, string>
            {
                { "2018年出品-京剧", "http://www.bavc.com.cn/c44167.htm" },
                { "2018年出品-老北京曲艺", "http://www.bavc.com.cn/c44168.htm" },
                { "2018年出品-评剧", "http://www.bavc.com.cn/c44169.htm" },

                { "2019年出品-京剧", "http://www.bavc.com.cn/c44417.htm" },
                { "2019年出品-曲艺", "http://www.bavc.com.cn/c44418.htm" },
            };

            // 转换为model
            List <ExcelSheetModel> sheetModels = null;
            if (System.IO.File.Exists(_CACHE_JSON_FILE))
            {
                try
                {
                    var jsonStr = System.IO.File.ReadAllText(_CACHE_JSON_FILE);
                    sheetModels = Newtonsoft.Json.JsonConvert.DeserializeObject <List <ExcelSheetModel> >(jsonStr);

                    System.Console.WriteLine($"从缓存文件{_CACHE_JSON_FILE}中读取记录成功");
                }
                catch (System.Exception ex)
                {
                    System.Console.WriteLine(ex.Message);
                    sheetModels = null;
                }
            }

            // 解析html
            if (sheetModels == null)
            {
                sheetModels = new List <ExcelSheetModel>();

                // 缓存html然后
                foreach (var item in downloadItems)
                {
                    var url = item.Value;
                    if (string.IsNullOrEmpty(url))
                    {
                        continue;
                    }

                    ExcelSheetModel model = new ExcelSheetModel();
                    model.Name       = item.Key;
                    model.MediaItems = ParseMediaItems(url);

                    sheetModels.Add(model);
                }

                // cache
                System.Console.WriteLine($"缓存文件{_CACHE_JSON_FILE}");
                System.IO.File.WriteAllText(
                    _CACHE_JSON_FILE,
                    Newtonsoft.Json.JsonConvert.SerializeObject(sheetModels)
                    );
                System.IO.File.WriteAllText(
                    System.IO.Path.GetFileNameWithoutExtension(_CACHE_JSON_FILE) + ".formatted" + System.IO.Path.GetExtension(_CACHE_JSON_FILE),
                    Newtonsoft.Json.JsonConvert.SerializeObject(sheetModels, Newtonsoft.Json.Formatting.Indented)
                    );
            }

            #endregion

            #region 手动修改一些错误

            // 根据文件名猜测artist时网页命名出现错误, 原文件名得到的是"林树森 华容道2 金少山"
            // "06 华容道2 林树森 金少山 胜利" 名称修改为 "06.华容道2 林树森 金少山 胜利"
            // 11 京剧红生大王《林树森专辑》
            NormalizeMp3FileName(sheetModels,
                                 "06 华容道2 林树森 金少山 胜利",
                                 "06.华容道2 林树森 金少山 胜利");

            // 2.京剧须生泰斗《马连良唱腔选》第一集
            NormalizeMp3FileName(sheetModels,   // 缺少 "马连良"
                                 "02.武家坡2 王玉蓉 百代",
                                 "02.武家坡2 马连良 王玉蓉 百代");
            NormalizeMp3FileName(sheetModels,
                                 "03.武家坡3 王玉蓉 百代",
                                 "03.武家坡3 马连良 王玉蓉 百代");
            NormalizeMp3FileName(sheetModels,
                                 "17.珠帘寨(沉静思)马连良 高亭",
                                 "17.珠帘寨(沉静思) 马连良 高亭");

            // 12.京剧一枝独秀《管绍华唱腔选》第一集
            NormalizeMp3FileName(sheetModels,
                                 "04.四郎探母5(坐宫) 王玉蓉 百代",
                                 "04.四郎探母9(坐宫) 管绍华 王玉蓉 百代");
            NormalizeMp3FileName(sheetModels,
                                 "05.四郎探母5(坐宫) 王玉蓉 百代",
                                 "05.四郎探母5(坐宫) 管绍华 王玉蓉 百代");
            NormalizeMp3FileName(sheetModels,
                                 "09. 四郎探母9(坐宫) 管绍华 王玉蓉 百代",
                                 "09.四郎探母9(坐宫) 管绍华 王玉蓉 百代");

            // 23.京剧《著名小生专辑》
            NormalizeMp3FileName(sheetModels,
                                 "19.得意缘3 (说破)毛世来 江世玉 丽歌",
                                 "19.得意缘3(说破) 毛世来 江世玉 丽歌");
            NormalizeMp3FileName(sheetModels,
                                 "20.得意缘4 (说破)毛世来 江世玉 丽歌",
                                 "20.得意缘4(说破) 毛世来 江世玉 丽歌");

            // 2.老北京曲艺大观《鼓界大王刘宝全》 第二集
            NormalizeMp3FileName(sheetModels,
                                 "09 博望坡1 刘宝全蓓开",
                                 "09 博望坡1 刘宝全 蓓开");

            NormalizeMp3FileName(sheetModels,
                                 "1-05.大保国-1言菊朋 百代",
                                 "1-05.大保国-1 言菊朋 百代");
            NormalizeMp3FileName(sheetModels,
                                 "1-07.卖马-1言菊朋、焦宝奎 百代",
                                 "1-07.卖马-1 言菊朋 焦宝奎 百代");
            NormalizeMp3FileName(sheetModels,
                                 "1-08.卖马-2言菊朋、焦宝奎 百代",
                                 "1-08.卖马-2 言菊朋 焦宝奎 百代");
            // NormalizeMp3FileName(sheetModels,
            //     "1-15.全部让徐州-1 言菊朋、马连昆 百代",
            //     "1-15.全部让徐州-1 言菊朋 马连昆 百代");
            // NormalizeMp3FileName(sheetModels,
            //     "1-16.全部让徐州-2 言菊朋、马连昆 百代",
            //     "1-16.全部让徐州-2 言菊朋 马连昆 百代");
            NormalizeMp3FileName(sheetModels,
                                 "1-17.黄鹤楼 言菊朋.吴彦衡.王又荃 百代",
                                 "1-17.黄鹤楼 言菊朋 吴彦衡 王又荃 百代");
            // NormalizeMp3FileName(sheetModels,
            //     "1-18.阳平关 言菊朋、吴彦衡 百代",
            //     "1-18.阳平关 言菊朋 吴彦衡 百代");
            NormalizeMp3FileName(sheetModels,   // 格式统一
                                 "2-05 战北原-1 言菊朋 蓓开",
                                 "2-05.战北原-1 言菊朋 蓓开");
            NormalizeMp3FileName(sheetModels,
                                 "2-06 战北原-2 言菊朋 蓓开",
                                 "2-06.战北原-2 言菊朋 蓓开");

            NormalizeMp3FileName(sheetModels,
                                 "3-01.捉放宿店-1 胜利",
                                 "3-01.捉放宿店-1 言菊朋 胜利");
            NormalizeMp3FileName(sheetModels,
                                 "3-02.捉放宿店-2 胜利",
                                 "3-02.捉放宿店-2 言菊朋 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "3-05.打渔杀家-1 言菊朋、云艳霞 胜利",
            //     "3-05.打渔杀家-1 言菊朋 云艳霞 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "3-06.打渔杀家-2 言菊朋、云艳霞 胜利",
            //     "3-06.打渔杀家-2 言菊朋 云艳霞 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "3-07.梅龙镇-1 言菊朋、云艳霞 胜利",
            //     "3-07.梅龙镇-1 言菊朋 云艳霞 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "3-08.梅龙镇-2 言菊朋、云艳霞 胜利",
            //     "3-08.梅龙镇-2 言菊朋 云艳霞 胜利");

            // 4. 《周信芳唱腔选》
            NormalizeMp3FileName(sheetModels,
                                 "01.徐策跑城-1周信芳 高亭",
                                 "01.徐策跑城-1 周信芳 高亭");
            // NormalizeMp3FileName(sheetModels,
            //     "09.投军别窑-1 周信芳、潘雪艳 蓓开",
            //     "09.投军别窑-1 周信芳 潘雪艳 蓓开");
            // NormalizeMp3FileName(sheetModels,
            //     "10.投军别窑-2 周信芳、潘雪艳 蓓开",
            //     "10.投军别窑-2 周信芳 潘雪艳 蓓开");
            // NormalizeMp3FileName(sheetModels,
            //     "15.九更天-1 周信芳、贯盛习 蓓开",
            //     "15.九更天-1 周信芳 贯盛习 蓓开");

            // 5. 《徐碧云唱腔选》
            // NormalizeMp3FileName(sheetModels,
            //     "04.骊珠梦-2 徐碧云、言菊朋 蓓开",
            //     "04.骊珠梦-2 徐碧云 言菊朋 蓓开");
            // NormalizeMp3FileName(sheetModels,
            //     "11.女起解-1 徐碧云、萧长华 高亭",
            //     "11.女起解-1 徐碧云 萧长华 高亭");

            // 6. 《郝寿臣唱腔选》
            NormalizeMp3FileName(sheetModels,
                                 "05.除三害(打窑)-1郝寿臣 蓓开",
                                 "05.除三害(打窑)-1 郝寿臣 蓓开");
            NormalizeMp3FileName(sheetModels,
                                 "06.除三害(打窑)-2郝寿臣 蓓开",
                                 "06.除三害(打窑)-2 郝寿臣 蓓开");
            NormalizeMp3FileName(sheetModels,
                                 "08.鸿门宴-2郝寿臣 胜利",
                                 "08.鸿门宴-2 郝寿臣 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "13.白良关 郝寿臣、裘桂仙 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "14.洪羊洞 郝寿臣、裘桂仙 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "15.普球山-1 郝寿臣、萧长华 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "16.普球山-2 郝寿臣、萧长华 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "17.飞虎梦-1 郝寿臣、吴富琴 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "18.飞虎梦-2 郝寿臣、吴富琴 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "19.荆轲传-1 郝寿臣、甄洪奎 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "20.荆轲传-2 郝寿臣、甄洪奎 百代",
            //     "");

            // 7. 《裘桂仙唱腔选》
            // NormalizeMp3FileName(sheetModels,
            //     "02.黄金台-1 时慧宝、裘桂仙 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "03.黄金台-2 时慧宝、裘桂仙 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "12.骂曹 言菊朋、裘桂仙 开明",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "13.二进宫 言菊朋、裘桂仙 开明",
            //     "");

            // 8. 《侯喜瑞、裘盛戎唱腔选》
            // NormalizeMp3FileName(sheetModels,
            //     "15.闹江州-1 金少山、裘盛戎 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "16.闹江州-2 金少山、裘盛戎 百代",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "17.连环套-1 马德成、裘盛戎 国乐",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "18.连环套-2 马德成、裘盛戎 国乐",
            //     "");

            // 9. 《萧长华唱腔选》
            // NormalizeMp3FileName(sheetModels,
            //     "03.八十八扯-1 马富禄、萧长华 胜利",
            //     "03.八十八扯-1 马富禄、萧长华 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "04.八十八扯-2 马富禄、萧长华 胜利",
            //     "04.八十八扯-2 马富禄、萧长华 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "05.八十八扯-3 马富禄、萧长华 胜利",
            //     "05.八十八扯-3 马富禄、萧长华 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "06.八十八扯-4 马富禄、萧长华 胜利",
            //     "06.八十八扯-4 马富禄、萧长华 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "07.打侄上坟-1 姜妙香、萧长华 胜利",
            //     "");
            // NormalizeMp3FileName(sheetModels,
            //     "08.打侄上坟-2 姜妙香、萧长华 胜利",
            //     "08.打侄上坟-2 姜妙香、萧长华 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "09.群英会-1 姜妙香、萧长华 胜利",
            //     "09.群英会-1 姜妙香、萧长华 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "10.群英会-2 姜妙香、萧长华 胜利",
            //     "10.群英会-2 姜妙香、萧长华 胜利");
            // NormalizeMp3FileName(sheetModels,
            //     "19.盘关-1 萧长华、萧盛萱 百代",
            //     "19.盘关-1 萧长华、萧盛萱 百代");
            // NormalizeMp3FileName(sheetModels,
            //     "20.盘关-2 萧长华、萧盛萱 百代",
            //     "20.盘关-2 萧长华 萧盛萱 百代");
            NormalizeMp3FileName(sheetModels,
                                 "21.打杠子-1萧长华 太平",
                                 "21.打杠子-1 萧长华 太平");

            // 10. 《汪派老生唱腔选》
            NormalizeMp3FileName(sheetModels,
                                 "01.文昭关-1王凤卿 蓓开",
                                 "01.文昭关-1 王凤卿 蓓开");
            NormalizeMp3FileName(sheetModels,
                                 "02.文昭关-2王凤卿 蓓开",
                                 "02.文昭关-2 王凤卿 蓓开");
            NormalizeMp3FileName(sheetModels,
                                 "03.朱砂痣-1王凤卿 蓓开",
                                 "03.朱砂痣-1 王凤卿 蓓开");
            NormalizeMp3FileName(sheetModels,
                                 "04.朱砂痣-2王凤卿 蓓开",
                                 "04.朱砂痣-2 王凤卿 蓓开");
            NormalizeMp3FileName(sheetModels,
                                 "13.红拂传-1 郭仲衡、杜丽云 长城",
                                 "13.红拂传-1 郭仲衡 杜丽云 长城");
            NormalizeMp3FileName(sheetModels,
                                 "15.举鼎观画-1郭仲衡 大中华",
                                 "15.举鼎观画-1 郭仲衡 大中华");
            NormalizeMp3FileName(sheetModels,
                                 "16.举鼎观画-2郭仲衡 大中华",
                                 "16.举鼎观画-2 郭仲衡 大中华");

            // 梨园名票唱腔选
            NormalizeMp3FileName(sheetModels,
                                 "01.汾河湾-1顾珏荪、张吾翼 百乐",
                                 "01.汾河湾-1 顾珏荪、张吾翼 百乐");

            // 2019年出品-曲艺
            NormalizeMp3FileName(sheetModels,
                                 "4-06.北派坠子《吕蒙正赶斋》2 乔清秀乔利元 胜利",
                                 "4-06.北派坠子《吕蒙正赶斋》2 乔清秀 乔利元 胜利");
            NormalizeMp3FileName(sheetModels,
                                 "4-07.北派坠子《马前泼水》1 乔清秀乔利元 胜利",
                                 "4-07.北派坠子《马前泼水》1 乔清秀 乔利元 胜利");
            NormalizeMp3FileName(sheetModels,
                                 "4-08.北派坠子《马前泼水》2 乔清秀乔利元 胜利",
                                 "4-08.北派坠子《马前泼水》2 乔清秀 乔利元 胜利");

            #endregion

            var result = sheetModels.ToArray();

            // 导入没有MP3/MP4地址的记录
            var errorFileName = System.IO.Path.Combine(StaticVariables.GetDownloadDir(), "errors.txt");
            var errorCount    = ExportHelper.ExportError(result, errorFileName);
            System.Console.WriteLine($"共找出{errorCount}个错误, log: {errorFileName}");

            // // 导出excel总数据
            //ExportHelper.ExportExcel("data.xlsx", result);

            // // 导出歌词
            ExportHelper.ExportLyricToWord(result);
            // 下载封面图片,MP3
            //ExportHelper.DownadMp3AndMp4(result);

            //return;

            // 生成MP3标签
            //ExportHelper.GenerateTagInfo(result);
        }