public void DownloadVideo()
        {
            string sTmpDir = BasePath + '\\' + PathHelper.ReplaceLimitChar(TidalVideo.Title, "-") + "TMP" + RandHelper.GetIntRandom(5, 9, 0);

            try
            {
                if (Directory.Exists(sTmpDir))
                {
                    Directory.Delete(sTmpDir, true);
                }
                PathHelper.Mkdirs(sTmpDir);

                long lCount = TidalVideoUrls.Count();
                for (int i = 0; i < lCount; i++)
                {
                    string sUrl  = TidalVideoUrls[i];
                    string sName = sTmpDir + '\\' + (100000 + i + 1).ToString() + ".ts";
                    bool   bFlag = (bool)DownloadFileHepler.Start(sUrl, sName, Timeout: 9999 * 1000);
                    if (bFlag == false)
                    {
                        Progress.Errlabel = "Download failed!";
                        goto ERR_POINT;
                    }

                    Progress.Update(i + 1, lCount);
                    if (Progress.IsCanceled)
                    {
                        goto CANCEL_POINT;
                    }
                }
                if (!MergerTsFiles(sTmpDir + '\\', FilePath))
                {
                    Progress.Errlabel = "FFmpeg merger err!";
                    goto ERR_POINT;
                }

                Progress.Update(lCount, lCount);
                Progress.IsComplete = true;
                UpdataFunc(this);

CANCEL_POINT:
                if (Directory.Exists(sTmpDir))
                {
                    Directory.Delete(sTmpDir, true);
                }
                return;
            }
            catch (Exception e)
            {
                Progress.Errlabel = "Err!" + e.Message;
            }

ERR_POINT:
            Progress.IsErr = true;
            UpdataFunc(this);
            if (Directory.Exists(sTmpDir))
            {
                Directory.Delete(sTmpDir, true);
            }
        }
Пример #2
0
        public void SubThreadFunc(object[] paras)
        {
            MainItem main  = (MainItem)paras[0];
            SubItem  sub   = (SubItem)paras[1];
            string   sPath = GetFilePath(main, sub);

            //CreatDir
            var di = new DirectoryInfo(Path.GetDirectoryName(sPath));

            if (!di.Exists)
            {
                di.Create();
            }

            if (sub.Type == "TRACK")
            {
                StreamUrl url = (StreamUrl)sub.DownloadUrl;
                if (url == null)
                {
                    sub.Status = AIGS.Common.Status.Err;
                    return;
                }
                DownloadFileHepler.Start(url.Url,
                                         sPath,
                                         Para.MainForm,
                                         paras,
                                         UpdateDownloadNotify,
                                         CompleteDownloadNotify,
                                         ErrDownloadNotify,
                                         ContentType: null,
                                         RetryNum: 3,
                                         UserAgent: null);
            }
            sub.Status = AIGS.Common.Status.Success;
        }
Пример #3
0
        public void DownloadTrack()
        {
            //Download
            bool bFlag = (bool)DownloadFileHepler.Start(TidalStream.Url,
                                                        FilePath,
                                                        RetryNum: 3,
                                                        UpdateFunc: UpdateDownloadNotify,
                                                        CompleteFunc: CompleteDownloadNotify,
                                                        ErrFunc: ErrDownloadNotify);

            //Err
            if (!bFlag)
            {
                Errlabel          = "Download Failed!";
                Progress.IsErr    = true;
                Progress.Errlabel = Errlabel;
                return;
            }

            try
            {
                //Decrypt / Set MetaData
                Tool.DecryptTrackFile(TidalStream, FilePath);
                var tfile = TagLib.File.Create(FilePath);
                tfile.Tag.Album        = TidalAlbum != null ? TidalAlbum.Title : "";
                tfile.Tag.Track        = (uint)TidalTrack.TrackNumber;
                tfile.Tag.Title        = TidalTrack.Title;
                tfile.Tag.AlbumArtists = new string[1] {
                    TidalTrack.Artist.Name
                };
                tfile.Tag.Copyright  = TidalTrack.CopyRight;
                tfile.Tag.Performers = new string[1] {
                    TidalTrack.Artist.Name
                };

                if (TidalAlbum != null && TidalAlbum.ReleaseDate.IsNotBlank())
                {
                    tfile.Tag.Year = (uint)AIGS.Common.Convert.ConverStringToInt(TidalAlbum.ReleaseDate.Split("-")[0]);
                }

                if (CoverPath != null)
                {
                    var pictures = new Picture[1];
                    pictures[0] = new Picture(CoverPath);
                    //pictures[0]  = new Picture(new ByteVector(Cover, Cover.Length));
                    tfile.Tag.Pictures = pictures;
                }
                tfile.Save();
            }
            catch
            {
                Errlabel          = "Decrypt-SetMetaData Failed!";
                Progress.IsErr    = true;
                Progress.Errlabel = Errlabel;
                return;
            }
        }
        //Update
        public void StartUpdate(string sVersion)
        {
            string url = GithubHelper.getFileUrl(Global.NAME_GITHUB_AUTHOR, Global.NAME_GITHUB_PROJECT, sVersion, Global.NAME_GITHUB_FILE);

            if (PathHelper.Mkdirs(Global.PATH_UPDATE) == false)
            {
                Dialog.Show(new MessageView(MessageBoxImage.Error, "Creat folder falied!", false));
                return;
            }

            DownloadFileHepler.StartAsync(url, Global.PATH_UPDATE + Global.NAME_GITHUB_FILE, null, UpdateDownloadNotify, CompleteDownloadNotify, ErrDownloadNotify, 3);
        }
        public void DownloadTrack()
        {
            // Check if the track was existing
            if (System.IO.File.Exists(FilePath))
            {
                Errlabel = "Existing";
                goto UPDATE_RETURN;
            }


            //Download
            bool bFlag = (bool)DownloadFileHepler.Start(TidalStream.Url,
                                                        FilePath,
                                                        RetryNum: 3,
                                                        Timeout: 99999 * 1000,
                                                        UpdateFunc: UpdateDownloadNotify,
                                                        CompleteFunc: CompleteDownloadNotify,
                                                        ErrFunc: ErrDownloadNotify);

            //Err
            if (!bFlag)
            {
                Errlabel       = "Download failed!";
                Progress.IsErr = true;
                goto UPDATE_RETURN;
            }

            if (!Tool.DecryptTrackFile(TidalStream, FilePath))
            {
                Errlabel       = "Decrypt Failed!";
                Progress.IsErr = true;
                goto UPDATE_RETURN;
            }

            string sLabel = Tool.SetMetaData(FilePath, TidalAlbum, TidalTrack, CoverPath);

            if (sLabel.IsNotBlank())
            {
                Errlabel       = "SetMetaData Failed! " + sLabel;
                Progress.IsErr = true;
                goto UPDATE_RETURN;
            }

UPDATE_RETURN:
            if (!Progress.IsErr)
            {
                Progress.IsComplete = true;
            }

            Progress.Errlabel = Errlabel;
            UpdataFunc(this);
        }
Пример #6
0
        public static long GetTotalDownloadSize(object oData, string sType)
        {
            long lRet = 0;

            if (sType == "ALBUM")
            {
                Album album = (Album)oData;
                foreach (Track item in album.Tracks)
                {
                    lRet += DownloadFileHepler.GetFileLength(item.StreamUrl.Url);
                }
            }
            return(lRet);
        }
        public void DownloadVideo()
        {
            string sTmpDir = BasePath + '\\' + PathHelper.ReplaceLimitChar(TidalVideo.Title, "-") + "TMP";

            if (Directory.Exists(sTmpDir))
            {
                Directory.Delete(sTmpDir, true);
            }
            PathHelper.Mkdirs(sTmpDir);

            long lCount = TidalVideoUrls.Count();

            for (int i = 0; i < lCount; i++)
            {
                string sUrl  = TidalVideoUrls[i];
                string sName = sTmpDir + '\\' + (100000 + i + 1).ToString() + ".ts";
                bool   bFlag = (bool)DownloadFileHepler.Start(sUrl, sName, RetryNum: 3);
                if (bFlag == false)
                {
                    Progress.Errlabel = "Download failed!";
                    goto ERR_POINT;
                }

                Progress.Update(i + 1, lCount);
                if (Progress.IsCancle)
                {
                    goto CANCLE_POINT;
                }
            }
            if (!MergerTsFiles(sTmpDir + '\\', FilePath))
            {
                Progress.Errlabel = "FFmpeg merger err!";
                goto ERR_POINT;
            }

            Progress.Update(lCount, lCount);
            Progress.IsComplete = true;
            UpdataFunc(this);
CANCLE_POINT:
            Directory.Delete(sTmpDir, true);
            return;

ERR_POINT:
            Progress.IsErr = true;
            UpdataFunc(this);
            Directory.Delete(sTmpDir, true);
        }
Пример #8
0
        public static StreamUrl GetStreamUrl(string sID, string sQuality)
        {
            string sRet = Get("tracks/" + sID + "/streamUrl", new Dictionary <string, string>()
            {
                { "soundQuality", sQuality }
            }, 3);

            if (string.IsNullOrEmpty(sRet) || !string.IsNullOrEmpty(Errmsg))
            {
                return(null);
            }

            StreamUrl aRet = JsonHelper.ConverStringToObject <StreamUrl>(sRet);

            aRet.FileSize = DownloadFileHepler.GetFileLength(aRet.Url);
            return(aRet);
        }
Пример #9
0
        public void DownloadTrack()
        {
            //Download
            bool bFlag = (bool)DownloadFileHepler.Start(TidalStream.Url,
                                                        FilePath,
                                                        RetryNum: 3,
                                                        UpdateFunc: UpdateDownloadNotify,
                                                        CompleteFunc: CompleteDownloadNotify,
                                                        ErrFunc: ErrDownloadNotify);

            //Err
            if (!bFlag)
            {
                Errlabel          = "Download Failed!";
                Progress.IsErr    = true;
                Progress.Errlabel = Errlabel;
                return;
            }

            try
            {
                //Decrypt / Set MetaData
                Tool.DecryptTrackFile(TidalStream, FilePath);
                var tfile = TagLib.File.Create(FilePath);
                tfile.Tag.Album        = TidalTrack.Album.Title;
                tfile.Tag.Track        = (uint)TidalTrack.TrackNumber;
                tfile.Tag.Title        = TidalTrack.Title;
                tfile.Tag.AlbumArtists = new string[1] {
                    TidalTrack.Artist.Name
                };
                tfile.Tag.Copyright  = TidalTrack.CopyRight;
                tfile.Tag.Performers = new string[1] {
                    TidalTrack.Artist.Name
                };
                tfile.Save();
            }
            catch
            {
                Errlabel          = "Decrypt-SetMetaData Failed!";
                Progress.IsErr    = true;
                Progress.Errlabel = Errlabel;
                return;
            }
        }
        //Update
        public void StartUpdate()
        {
            Progress.ValueInt  = 0;
            CountIncreSize     = 0;
            ShowProgress       = Visibility.Visible;
            DownloadStatusInfo = Language.Get("strmsgGetNewVersionUrl");

            string url = GithubHelper.getFileUrl(Global.NAME_GITHUB_AUTHOR, Global.NAME_GITHUB_PROJECT, LastVersion, Global.NAME_GITHUB_FILE);

            if (PathHelper.Mkdirs(Global.PATH_UPDATE) == false)
            {
                DownloadStatusInfo = Language.Get("strmsgCreatUpdateFolderFailed");
                EndUpdate();
                return;
            }

            DownloadStatusInfo = Language.Get("strmsgStartUpdate");
            Progress.SetStatus(ProgressHelper.STATUS.RUNNING);
            StartTime = TimeHelper.GetCurrentTime();
            LoginKey key = Tools.GetKey();

            DownloadFileHepler.StartAsync(url, Global.PATH_UPDATE + Global.NAME_GITHUB_FILE, null, UpdateDownloadNotify, CompleteDownloadNotify, ErrDownloadNotify, 3, Proxy: key.Proxy);
        }
        public void Download()
        {
            try
            {
                LoginKey key = Tools.GetKey();

                //GetStream
                Progress.StatusMsg        = "GetStream...";
                (Progress.Errmsg, Stream) = Client.GetTrackStreamUrl(key, TidalTrack.ID, Settings.AudioQuality).Result;
                if (Progress.Errmsg.IsNotBlank() || Stream == null)
                {
                    goto ERR_RETURN;
                }

                Codec = Stream.Codec;
                Progress.StatusMsg = "GetStream success...";

                if (TidalAlbum == null && TidalTrack.Album != null)
                {
                    string tmpmsg;
                    (tmpmsg, TidalAlbum) = Client.GetAlbum(key, TidalTrack.Album.ID, false).Result;
                }

                //Get path
                string path = Tools.GetTrackPath(Settings, TidalTrack, Stream, TidalAlbum, TidalPlaylist);

                //Check if song downloaded already
                string checkpath = Settings.OnlyM4a ? path.Replace(".mp4", ".m4a") : path;
                if (Settings.CheckExist && System.IO.File.Exists(checkpath))
                {
                    Progress.UpdateInt(100, 100);
                    Progress.SetStatus(ProgressHelper.STATUS.COMPLETE);
                    goto CALL_RETURN;
                }

                //Download
                Progress.StatusMsg = "Start...";
                for (int i = 0; i < 50 && Progress.GetStatus() != ProgressHelper.STATUS.CANCLE; i++)
                {
                    StartTime = TimeHelper.GetCurrentTime();
                    if ((bool)DownloadFileHepler.Start(Stream.Url, path, Timeout: 5 * 1000, UpdateFunc: UpdateDownloadNotify, ErrFunc: ErrDownloadNotify, Proxy: key.Proxy))
                    {
                        //Decrypt
                        if (!Tools.DecryptTrackFile(Stream, path))
                        {
                            Progress.Errmsg = "Decrypt failed!";
                            goto ERR_RETURN;
                        }

                        if (Settings.OnlyM4a)
                        {
                            (Progress.Errmsg, path) = Tools.ConvertMp4ToM4a(path, Stream);
                            if (Progress.Errmsg.IsNotBlank())
                            {
                                goto ERR_RETURN;
                            }
                        }

                        //SetMetaData
                        if (TidalAlbum == null)
                        {
                            (Progress.Errmsg, TidalAlbum) = Client.GetAlbum(key, TidalTrack.Album.ID, false).Result;
                        }
                        Progress.Errmsg = Tools.SetMetaData(path, TidalAlbum, TidalTrack);
                        if (Progress.Errmsg.IsNotBlank())
                        {
                            Progress.Errmsg = "Set metadata failed!" + Progress.Errmsg;
                            goto ERR_RETURN;
                        }

                        Progress.SetStatus(ProgressHelper.STATUS.COMPLETE);
                        goto CALL_RETURN;
                    }
                }
                Progress.Errmsg = "Download failed!";
                System.IO.File.Delete(path);
            }
            catch (Exception e)
            {
                Progress.Errmsg = "Download failed!" + e.Message;
            }

ERR_RETURN:
            if (Progress.GetStatus() == ProgressHelper.STATUS.CANCLE)
            {
                goto CALL_RETURN;
            }
            Progress.SetStatus(ProgressHelper.STATUS.ERROR);

CALL_RETURN:
            TellParentOver();

            DownloadSpeedString = "";
        }
Пример #12
0
        public void DownloadTrack()
        {
            string Errlabel = "";

            //GetStream
            Progress.StatusMsg = "GetStream...";
            StreamUrl TidalStream = TidalTool.getStreamUrl(TidalTrack.ID.ToString(), Quality, out Errlabel);

            if (Errlabel.IsNotBlank())
            {
                goto ERR_RETURN;
            }

            //Get path
            FilePath = TidalTool.getTrackPath(OutputDir, TidalAlbum, TidalTrack, TidalStream.Url, AddHyphen, TidalPlaylist, artistBeforeTitle: ArtistBeforeTitle);

            //Check if song is downloaded already
            string CheckName = OnlyM4a ? FilePath.Replace(".mp4", ".m4a") : FilePath;

            if (CheckExist && System.IO.File.Exists(CheckName))
            {
                Progress.Update(100, 100);
                Progress.SetStatus(ProgressHelper.STATUS.COMPLETE);
                return;
            }

            //Get contributors
            ObservableCollection <Contributor> pContributors = TidalTool.getTrackContributors(TidalTrack.ID.ToString(), out Errlabel);

            //To chinese
            if (ToChinese)
            {
                CloudMusicAlbum cloalbum = Chinese.matchAlbum(TidalAlbum.Title, TidalAlbum.Artist.Name);
                string          chnname  = Chinese.convertSongTitle(TidalTrack.Title, cloalbum);
                if (chnname != TidalTrack.Title)
                {
                    FilePath         = TidalTool.getTrackPath(OutputDir, TidalPlaylist != null ? null : TidalAlbum, TidalTrack, TidalStream.Url, AddHyphen, TidalPlaylist, chnname, artistBeforeTitle: ArtistBeforeTitle);
                    TidalTrack.Title = chnname;
                }
            }

            //Download
            Progress.StatusMsg = "Start...";
            for (int i = 0; i < 100 && Progress.GetStatus() != ProgressHelper.STATUS.CANCLE; i++)
            {
                if ((bool)DownloadFileHepler.Start(TidalStream.Url, FilePath, Timeout: 5 * 1000, UpdateFunc: UpdateDownloadNotify, ErrFunc: ErrDownloadNotify, Proxy:TidalTool.PROXY))
                {
                    //Decrypt
                    if (!TidalTool.DecryptTrackFile(TidalStream, FilePath))
                    {
                        Errlabel = "Decrypt failed!";
                        goto ERR_RETURN;
                    }

                    if (OnlyM4a)
                    {
                        string sNewName;
                        if (!TidalTool.ConvertMp4ToM4a(FilePath, out sNewName))
                        {
                            Errlabel = "Convert mp4 to m4a failed!";
                            goto ERR_RETURN;
                        }
                        else
                        {
                            FilePath = sNewName;
                        }
                    }

                    //SetMetaData
                    if (TidalAlbum == null && TidalTrack.Album != null)
                    {
                        string sErrcode = null;
                        TidalAlbum = TidalTool.getAlbum(TidalTrack.Album.ID.ToString(), out sErrcode);
                    }
                    string sLabel = TidalTool.SetMetaData(FilePath, TidalAlbum, TidalTrack, TidalTool.getAlbumCoverPath(OutputDir, TidalAlbum), pContributors);
                    if (sLabel.IsNotBlank())
                    {
                        Errlabel = "Set metadata failed!";
                        goto ERR_RETURN;
                    }

                    Progress.SetStatus(ProgressHelper.STATUS.COMPLETE);
                    return;
                }
            }
            Errlabel = "Download failed!";

ERR_RETURN:
            if (Progress.GetStatus() == ProgressHelper.STATUS.CANCLE)
            {
                return;
            }

            ErrlabelHeight = 15;
            Progress.SetStatus(ProgressHelper.STATUS.ERROR);
            Progress.Errmsg = Errlabel;
        }
Пример #13
0
        public void DownloadTrack()
        {
            //GetStream
            Progress.StatusMsg = "GetStream...";
            string    Errlabel    = "";
            StreamUrl TidalStream = TidalTool.getStreamUrl(TidalTrack.ID.ToString(), Quality, out Errlabel);

            if (Errlabel.IsNotBlank())
            {
                goto ERR_RETURN;
            }
            FilePath = TidalTool.getAlbumTrackPath(OutputDir, TidalAlbum, TidalTrack, TidalStream.Url);

            //Download
            Progress.StatusMsg = "Start...";
            for (int i = 0; i < 100 && Progress.GetStatus() != ProgressHelper.STATUS.CANCLE; i++)
            {
                if ((bool)DownloadFileHepler.Start(TidalStream.Url, FilePath, Timeout: 5 * 1000, UpdateFunc: UpdateDownloadNotify, ErrFunc: ErrDownloadNotify))
                {
                    //Decrypt
                    if (!TidalTool.DecryptTrackFile(TidalStream, FilePath))
                    {
                        Errlabel = "Decrypt failed!";
                        goto ERR_RETURN;
                    }

                    if (OnlyM4a)
                    {
                        string sNewName;
                        if (!TidalTool.ConvertMp4ToM4a(FilePath, out sNewName))
                        {
                            Errlabel       = "Convert mp4 to m4a failed!";
                            ErrlabelHeight = 15;
                        }
                        else
                        {
                            FilePath = sNewName;
                        }
                    }

                    //SetMetaData
                    string sLabel = TidalTool.SetMetaData(FilePath, TidalAlbum, TidalTrack, TidalTool.getAlbumCoverPath(OutputDir, TidalAlbum));
                    if (sLabel.IsNotBlank())
                    {
                        Errlabel = "Set metadata failed!";
                        goto ERR_RETURN;
                    }
                    Progress.SetStatus(ProgressHelper.STATUS.COMPLETE);
                    return;
                }
            }
            Errlabel = "Download failed!";

ERR_RETURN:
            if (Progress.GetStatus() == ProgressHelper.STATUS.CANCLE)
            {
                return;
            }

            ErrlabelHeight = 15;
            Progress.SetStatus(ProgressHelper.STATUS.ERROR);
            Progress.Errmsg = Errlabel;
        }
Пример #14
0
        public void DownloadTrack()
        {
            string Errlabel = "";

            //GetStream
            Progress.StatusMsg = "GetStream...";
            StreamUrl TidalStream = TidalTool.getStreamUrl(TidalTrack.ID.ToString(), Quality, out Errlabel);

            if (Errlabel.IsNotBlank())
            {
                goto ERR_RETURN;
            }

            //Get path
            FilePath = TidalTool.getTrackPath(OutputDir, TidalAlbum, TidalTrack, TidalStream.Url, AddHyphen, TidalPlaylist);

            //Get contributors
            ObservableCollection <Contributor> pContributors = TidalTool.getTrackContributors(TidalTrack.ID.ToString(), out Errlabel);

            //Download
            Progress.StatusMsg = "Start...";
            for (int i = 0; i < 100 && Progress.GetStatus() != ProgressHelper.STATUS.CANCLE; i++)
            {
                if ((bool)DownloadFileHepler.Start(TidalStream.Url, FilePath, Timeout: 5 * 1000, UpdateFunc: UpdateDownloadNotify, ErrFunc: ErrDownloadNotify, Proxy:TidalTool.PROXY))
                {
                    //Decrypt
                    if (!TidalTool.DecryptTrackFile(TidalStream, FilePath))
                    {
                        Errlabel = "Decrypt failed!";
                        goto ERR_RETURN;
                    }

                    if (OnlyM4a)
                    {
                        string sNewName;
                        if (!TidalTool.ConvertMp4ToM4a(FilePath, out sNewName))
                        {
                            Errlabel       = "Convert mp4 to m4a failed!";
                            ErrlabelHeight = 15;
                        }
                        else
                        {
                            FilePath = sNewName;
                        }
                    }

                    //SetMetaData
                    if (TidalAlbum == null && TidalTrack.Album != null)
                    {
                        string sErrcode = null;
                        TidalAlbum = TidalTool.getAlbum(TidalTrack.Album.ID.ToString(), out sErrcode);
                    }
                    string sLabel = TidalTool.SetMetaData(FilePath, TidalAlbum, TidalTrack, TidalTool.getAlbumCoverPath(OutputDir, TidalAlbum), pContributors);
                    if (sLabel.IsNotBlank())
                    {
                        Errlabel = "Set metadata failed!";
                        goto ERR_RETURN;
                    }
                    Progress.SetStatus(ProgressHelper.STATUS.COMPLETE);
                    return;
                }
            }
            Errlabel = "Download failed!";

ERR_RETURN:
            if (Progress.GetStatus() == ProgressHelper.STATUS.CANCLE)
            {
                return;
            }

            ErrlabelHeight = 15;
            Progress.SetStatus(ProgressHelper.STATUS.ERROR);
            Progress.Errmsg = Errlabel;
        }
Пример #15
0
        public void Download()
        {
            string Errlabel = "";

            //GetStream
            Progress.StatusMsg = "GetStream...";
            StreamUrl TidalStream = TidalTool.getStreamUrl(TidalTrack.ID.ToString(), Quality, out Errlabel);

            if (Errlabel.IsNotBlank() || TidalStream == null)
            {
                goto ERR_RETURN;
            }
            if (TidalStream.Codec != "ac4" && TidalStream.Codec != "mha1")
            {
                if (Quality >= eSoundQuality.LOSSLESS)
                {
                    if (TidalStream.Url.Contains(".m4a") || TidalStream.Url.Contains(".mp4"))
                    {
                        StreamUrl TidalStream2 = TidalTool.getStreamUrl2(TidalTrack.ID.ToString(), Quality, out Errlabel);
                        if (Errlabel.IsBlank() && TidalStream2 != null)
                        {
                            TidalStream = TidalStream2;
                        }
                        Errlabel = "";
                    }
                }
            }
            Codec = TidalStream.Codec;
            Progress.StatusMsg = "GetStream success...";

            //Get path
            FilePath = TidalTool.getTrackPath(OutputDir, TidalAlbum, TidalTrack, TidalStream.Url,
                                              AddHyphen, TidalPlaylist, artistBeforeTitle: ArtistBeforeTitle, addexplicit: AddExplict,
                                              addYear: AddYear, useTrackNumber: UseTrackNumber);


            //Check if song is downloaded already
            string CheckName = OnlyM4a ? FilePath.Replace(".mp4", ".m4a") : FilePath;

            if (CheckExist && System.IO.File.Exists(CheckName))
            {
                Progress.UpdateInt(100, 100);
                Progress.SetStatus(ProgressHelper.STATUS.COMPLETE);
                goto CALL_RETURN;
            }

            //Get contributors
            Progress.StatusMsg = "GetContributors...";
            ObservableCollection <Contributor> pContributors = TidalTool.getTrackContributors(TidalTrack.ID.ToString(), out Errlabel);

            //Download
            Progress.StatusMsg = "Start...";
            for (int i = 0; i < 100 && Progress.GetStatus() != ProgressHelper.STATUS.CANCLE; i++)
            {
                if ((bool)DownloadFileHepler.Start(TidalStream.Url, FilePath, Timeout: 5 * 1000, UpdateFunc: UpdateDownloadNotify, ErrFunc: ErrDownloadNotify, Proxy: TidalTool.PROXY))
                {
                    //Decrypt
                    if (!TidalTool.DecryptTrackFile(TidalStream, FilePath))
                    {
                        Errlabel = "Decrypt failed!";
                        goto ERR_RETURN;
                    }

                    if (OnlyM4a && Path.GetExtension(FilePath).ToLower().IndexOf("mp4") >= 0)
                    {
                        if (TidalStream.Codec != "ac4" && TidalStream.Codec != "mha1")
                        {
                            string sNewName;
                            if (!Config.IsFFmpegExist())
                            {
                                Errlabel = "Convert mp4 to m4a failed!(FFmpeg is not exist!)";
                                goto ERR_RETURN;
                            }
                            if (!TidalTool.ConvertMp4ToM4a(FilePath, out sNewName))
                            {
                                Errlabel = "Convert mp4 to m4a failed!(No reason, Please feedback!)";
                                goto ERR_RETURN;
                            }
                            else
                            {
                                FilePath = sNewName;
                            }
                        }
                    }

                    //SetMetaData
                    if (TidalAlbum == null && TidalTrack.Album != null)
                    {
                        string sErrcode = null;
                        TidalAlbum = TidalTool.getAlbum(TidalTrack.Album.ID.ToString(), out sErrcode);
                    }
                    string sLabel = TidalTool.SetMetaData(FilePath, TidalAlbum, TidalTrack, TidalTool.getAlbumCoverPath(OutputDir, TidalAlbum, AddYear), pContributors);
                    if (sLabel.IsNotBlank())
                    {
                        Errlabel = "Set metadata failed!" + sLabel;
                        goto ERR_RETURN;
                    }

                    Progress.SetStatus(ProgressHelper.STATUS.COMPLETE);
                    goto CALL_RETURN;
                }
            }
            Errlabel = "Download failed!";

ERR_RETURN:
            if (Progress.GetStatus() == ProgressHelper.STATUS.CANCLE)
            {
                goto CALL_RETURN;
            }
            Progress.SetStatus(ProgressHelper.STATUS.ERROR);
            Progress.Errmsg = Errlabel;

CALL_RETURN:
            TellParentOver();
        }