public void Reset() { _detail = null; VideoPartCollection.Clear(); TagCollection.Clear(); StaffCollection.Clear(); LikeButton.IsCheck = false; CoinButton.IsCheck = false; FavoriteButton.IsCheck = false; PlayCountBlock.Text = "-"; DanmakuCountBlock.Text = "-"; CommentButton.Text = "-"; RepostButton.Text = "-"; DescriptionBlock.Text = "--"; UPAvatar.ProfilePicture = null; UPNameBlock.Text = "-"; SelectLikeCheckBox.IsChecked = true; FavoriteListView.ItemsSource = null; if (PlayBackupCollection.Count > 0) { int index = PlayBackupCollection.IndexOf(PlayBackupCollection.Where(p => p.aid == videoId).FirstOrDefault()); PlayListContainer.ShowListView.SelectedIndex = index; if (index != -1) { PlayListContainer.ShowListView.ScrollIntoView(PlayBackupCollection[index], ScrollIntoViewAlignment.Leading); } } }
private void OnVideoInfoClicked(object sender, EventArgs e) { VideoDetail ad = new VideoDetail(); ad.UpdateHandler += OnUpdateHandler; ad.Video = (sender as VideoInfo).Video; ad.ShowDialog(); }
public void ShowRepostPopup(string origin, VideoDetail video) { if (_repostPopup == null) { _repostPopup = new RepostPopup(); } _repostPopup.ShowPopup(); _repostPopup.Init(origin, video); }
public async Task <IActionResult> Create([FromForm] VideoDetail model) { var result = await _videosService.CreateAsync(model); if (result.IsSuccess) { return(Ok(result)); } return(BadRequest(result)); }
public ActionResult GetVideoDetail() { var stream = HttpContext.Request.InputStream; string requestJson = new StreamReader(stream).ReadToEnd(); //json 字符串在此 JObject jo = (JObject)JsonConvert.DeserializeObject(requestJson); int videoCollectionId = Convert.ToInt32(jo["videoId"].ToString()); VideoCollections videoCollection = db.VideoCollections.Find(videoCollectionId); List <Videos> videos = db.Videos.Where(item => item.VideoCollectionId == videoCollectionId).ToList(); VideoDetailData videoDetailData = new VideoDetailData(); videoDetailData.Id = videoCollection.Id; videoDetailData.Title = videoCollection.Title; videoDetailData.CreateTime = videoCollection.CreateTime.ToString("yyyy-MM-dd"); videoDetailData.Level = videoCollection.Grade; videoDetailData.Tags = videoCollection.Tags; videoDetailData.Content = "/admin/video/preview/" + videoCollectionId; List <VideoDetail> videoDetails = new List <VideoDetail>(); foreach (Videos video in videos) { VideoDetail videoDetail = new VideoDetail(); videoDetail.Id = video.Id; int originalWidth = 0; int originalHeight = 0; if (video.VideoIndex != null) { videoDetail.PicAD = video.VideoIndex; System.Drawing.Image imgOriginal = System.Drawing.Image.FromFile(Server.MapPath(HttpUtility.UrlDecode(videoCollection.PicIndex))); originalWidth = imgOriginal.Width; originalHeight = imgOriginal.Height; } else { videoDetail.PicAD = ""; } videoDetail.PicWidth = originalWidth; videoDetail.PicHeight = originalHeight; videoDetail.Title = video.Title; if (video.VideoLink != null) { videoDetail.VideoLink = video.VideoLink; } else { videoDetail.VideoLink = ""; } videoDetails.Add(videoDetail); } videoDetailData.VideoDetail = videoDetails; return(Json(new { data = videoDetailData })); }
private static void TestGetInfo(string videoId, string languageCode) { VideoDetail vd = vcc.GetVideoInfo(videoId); if (vd.Languages.Count > 0) { string vlUri = (from l in vd.Languages where l.Code == languageCode select l).FirstOrDefault().VideoLanguageUri; if (!string.IsNullOrWhiteSpace(vlUri)) { var vlDetails = vcc.GetLanguageDetails(vlUri); Console.WriteLine("Video language Detail: " + vlDetails); } } }
private async void VideoPartGridView_ItemClick(object sender, ItemClickEventArgs e) { var data = e.ClickedItem as VideoDetail; if (VideoPartGridView.SelectionMode == ListViewSelectionMode.Multiple) { return; } if (data != null) { _selecVideo = data; StopMedia(); GetVideoSourceData(); } }
public void HidePopup() { _tempTopic = null; _tempVideo = null; _tempBangumi = null; _tempPart = null; RepostBox.Text = string.Empty; OriginBlock.Text = string.Empty; AtUserCollection.Clear(); AtUserCollection.Add(new Owner()); SearchCollection.Clear(); UserSearchBox.Text = string.Empty; PopupOut.Begin(); PopupOut.Completed -= PopupOut_Completed; PopupOut.Completed += PopupOut_Completed; }
private async void GetDetailData() { DetailData dd = new DetailData(); var url = AcFunAPI.GetContentUrl(_SeleCContent.ContentId); await dd.GetData(url); if (dd.ListOfACContent == null || dd.ListOfACContent.Count == 0) { //todo MSGSHOW("获取资源失败!"); return; } _SeleCContent = dd.ListOfACContent[0]; _selecVideo = _SeleCContent.DetailVideos[0]; GetVideoSourceData(); AddVideoInfoDetail(); }
private async void DoBackgroundDownload(VideoDetail vd, VideosSource vs) { var downloadData = new DownloadData(); downloadData.content = vd; int i = 0; foreach (var item in vs.RealUrl) { var filename = vd.ACTitle + "_" + vd.Title + "_" + i + ".flv"; filename = filename.Replace("\\", "").Replace("/", "").Replace(":", "").Replace("*", "").Replace("?", ""). Replace("\"", "").Replace("<", "").Replace(">", "").Replace("|", ""); var uri = new Uri(item); downloadData.VideoFiles.Add(filename); i++; // List<Task> task = new List<Task>(); try { //task.Add(StartOneDownload(filename, uri, downloadData)); StartOneDownload(filename, uri, downloadData); } catch (Exception ex) { LocalStorageFunc.DeleteVideoFile(filename); foreach (var dd in downloadDatas) { if (dd.content.DanmakuId == vd.DanmakuId) { downloadDatas.Remove(dd); break; } } MSGSHOW("下载错误:\r\n " + ex.Message); return; } finally { } } downloadDatas.Add(downloadData); }
private async void GetBangumiVideoData() { if (_SeleCContent.Bangumi.BangumiId != null) { var url = AcFunAPI.GetBangumiContentUrl(_SeleCContent.Bangumi.BangumiId); BangumiDetailData bdd = new BangumiDetailData(); await bdd.GetData(url); if (bdd.ListOfACContent == null) { MSGSHOW("资源获取失败"); return; } _SeleCContent = bdd.ListOfACContent[0]; _selecVideo = _SeleCContent.DetailVideos[0]; GetVideoSourceData(); AddVideoInfoDetail(); } }
private async void GetUrl(VideoDetail content) { var vsd = new VideoSourceData(); var url = AcFunAPI.GetVideoSrcUrl(content.VideoId); await vsd.GetData(url); if (vsd.ListofVideoSourceData == null || vsd.ListofVideoSourceData.Count == 0) { MSGSHOW("下载失败:\r\n 获取视频地址失败!"); } if (vsd.ListofVideoSourceData.Count > 1) { bool hasSuper = false; foreach (var key in vsd.ListofVideoSourceData.Keys) { if (key == "超清") { hasSuper = true; } } if (hasSuper) { DoBackgroundDownload(content, vsd.ListofVideoSourceData["超清"]); } else { DoBackgroundDownload(content, vsd.ListofVideoSourceData["高清"]); } // MSGSHOW(vsd.ListofVideoSourceData); } else { foreach (var dic in vsd.ListofVideoSourceData) { DoBackgroundDownload(content, dic.Value); break; } } }
// GET: Video public ActionResult Index() { string root = @"E:\VidCheck"; string[] VidEntries = Directory.GetFiles(root); foreach (string VidFiles in VidEntries) { using (var VideoFrameReader = new VideoFrameReader(VidFiles)) { var Duration = VideoFrameReader.Duration; var Width = VideoFrameReader.Width; var Height = VideoFrameReader.Height; var CodecName = VideoFrameReader.CodecName; var CodecTag = VideoFrameReader.CodecTag; var BitRate = VideoFrameReader.BitRate; var FrameRate = VideoFrameReader.FrameRate; var CodecDescription = VideoFrameReader.CodecDescription; var CurrentFrameNumber = VideoFrameReader.CurrentFrameNumber; /*VideoDetail1 viewModel = new VideoDetail1(); * viewModel.DictionaryTest = new Dictionary<string, string>(); * viewModel.DictionaryTest.Add("key1", "value1"); * viewModel.DictionaryTest.Add("key2", "value2");*/ VideoDetail video = new VideoDetail(); video.Length = Duration.ToString(); video.FrameWidth = Width.ToString(); video.FrameHeight = Height.ToString(); video.CodecName = CodecName.ToString(); video.CodecTag = CodecTag.ToString(); video.BitRate = BitRate.ToString(); video.FrameRate = FrameRate.ToString(); video.CodecDescription = CodecDescription.ToString(); video.CurrentFrameNumber = CurrentFrameNumber.ToString(); db.VideoDetails.Add(video); } db.SaveChanges(); } return(View()); }
/// <summary> /// 在新窗口中播放视频 /// </summary> /// <param name="video">视频ID</param> /// <param name="cid">分片ID</param> public async void PlayVideoSeparate(VideoDetail video, int cid, bool isCloseCurrentPage = true) { CoreApplicationView newView = CoreApplication.CreateNewView(); int newViewId = 0; await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Frame frame = new Frame(); frame.Navigate(typeof(MiniPlayerPage), new Tuple <VideoDetail, int>(video, cid)); Window.Current.Content = frame; // You have to activate the window in order to show it later. Window.Current.Activate(); newViewId = ApplicationView.GetForCurrentView().Id; }); bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId); if (!App._isTabletMode && CurrentPageType == typeof(VideoPage) && isCloseCurrentPage) { CurrentPagePanel.MainPageBack(); } }
private void Reset() { _detail = null; VideoPartCollection.Clear(); RelatedCollection.Clear(); TagCollection.Clear(); StaffCollection.Clear(); LikeButton.IsCheck = false; CoinButton.IsCheck = false; FavoriteButton.IsCheck = false; AutoLoopSwitch.IsOn = false; VideoPlayer.AutoLoop = false; PlayCountBlock.Text = "-"; DanmukuCountBlock.Text = "-"; CommentButton.Text = "评论"; RepostButton.Text = "-"; DescriptionBlock.Text = "--"; UPAvatar.ProfilePicture = null; UPNameBlock.Text = "-"; SelectLikeCheckBox.IsChecked = true; FavoriteListView.ItemsSource = null; FollowButton.Style = UIHelper.GetStyle("PrimaryAsyncButtonStyle"); FollowButton.Text = "关注"; if (_isPlayList) { int index = PlayBackupCollection.IndexOf(PlayBackupCollection.Where(p => p.aid == videoId).FirstOrDefault()); PlayListContainer.ShowListView.SelectedIndex = index; if (index != -1) { PlayListContainer.ShowListView.ScrollIntoView(PlayBackupCollection[index], ScrollIntoViewAlignment.Leading); } } }
public VideoLanguageDetail GetVideoInfo(string videoId, string languageCode) { VideoDetail vd = vcc.GetVideoInfo(videoId); if (vd.Languages.Count > 0) { string vlUri = (from l in vd.Languages where l.Code == languageCode select l).FirstOrDefault().VideoLanguageUri; if (!string.IsNullOrWhiteSpace(vlUri)) { return(vcc.GetLanguageDetails(vlUri)); //Console.WriteLine("Video language Detail: " + vlDetails); } else { return(null); } } else { return(null); } }
public async Task Refresh() { if (PageContainer.Visibility == Visibility.Collapsed) { PageContainer.Visibility = Visibility.Visible; } Reset(); var tip = new WaitingPopup("加载视频中..."); tip.ShowPopup(); var detail = await _videoService.GetVideoDetailAsync(videoId, _fromSign, bvId); if (detail != null && detail.aid > 0) { _detail = detail; if (InitDetail()) { await VideoPlayer.Init(_detail, _currentPartId); } } App.AppViewModel.CurrentPagePanel.PageScrollViewer.ChangeView(0, 0, 1); tip.HidePopup(); }
public async Task <OperationResponse <VideoDetail> > CreateAsync(VideoDetail model) { var similarVideo = await _unitOfWork.Videos.GetByTitleAsync(model.Title); if (similarVideo != null) { return new OperationResponse <VideoDetail> { IsSuccess = false, Message = "Another video has the same title" } } ; if (model.ThumbFile == null) { return new OperationResponse <VideoDetail> { IsSuccess = false, Message = "No thumbnail file provided." } } ; string thumbUrl = string.Empty; try { thumbUrl = await _storage.SaveFileAsync(model.ThumbFile, "Uploads"); } catch (BadImageFormatException) { return(new OperationResponse <VideoDetail> { IsSuccess = false, Message = "Please upload a thumbnail image." }); } var video = new Video { Category = model.Category, Description = model.Description, Likes = 0, Views = 0, ThumbURL = thumbUrl, Title = model.Title, VideoURL = model.VideoURL, PublishingDate = model.PublishingDate, VideoPrivacy = model.VideoPrivacy, Tags = model.Tags?.Select(t => new Tag { Name = t, }).ToList(), }; await _unitOfWork.Videos.CreateAsync(video); await _unitOfWork.CommitChangesAsync(_identity.UserID); model.Id = video.Id; model.ThumbFile = null; model.ThumbURL = $"{_env.ApiUrl}/{thumbUrl}"; return(new OperationResponse <VideoDetail> { IsSuccess = true, Message = "Video has been created", Data = model }); }
public async Task <OperationResponse <VideoDetail> > UpdateAsync(VideoDetail model) { var video = await _unitOfWork.Videos.GetByIdAsync(model.Id); if (video == null) { return new OperationResponse <VideoDetail> { IsSuccess = false, Data = null, Message = "Video not found" } } ; //Check the thumb image var thumbUrl = video.ThumbURL; if (model.ThumbFile != null) { try { thumbUrl = await _storage.SaveFileAsync(model.ThumbFile, "Uploads"); _storage.RemoveFile(video.ThumbURL); } catch (BadImageFormatException) { return(new OperationResponse <VideoDetail> { IsSuccess = false, Message = "Please upload a thumbnail image." }); } } _unitOfWork.Videos.RemoveTags(video); video.Title = model.Title; video.Description = model.Description; video.VideoPrivacy = model.VideoPrivacy; video.Category = model.Category; video.PublishingDate = model.PublishingDate; video.ThumbURL = thumbUrl; video.Tags = model.Tags?.Select(t => new Tag { Name = t, }).ToList(); await _unitOfWork.CommitChangesAsync(_identity.UserID); model.ThumbFile = null; model.ThumbURL = $"{_env.ApiUrl}/{thumbUrl}"; return(new OperationResponse <VideoDetail> { IsSuccess = true, Message = "Video has been updated", Data = model }); } }
public void Init(string origin, VideoDetail video) { OriginBlock.Text = origin; _tempVideo = video; }
public Task <OperationResponse <VideoDetail> > UpdateAsync(VideoDetail model) { throw new NotImplementedException(); }
public void SecilenVideoChanged(VideoDetail video) { secilenVideo = video; }
public async Task Init(VideoDetail detail, int partId = 0) { Reset(); App.AppViewModel.CurrentPlayerType = Models.Enums.PlayerType.Video; App.AppViewModel.CurrentVideoPlayer = VideoPlayer; _detail = detail; _currentPartId = partId; TabletMainPage.Current.SetBackgroundImage(_detail.pic); if (!string.IsNullOrEmpty(_detail.redirect_url)) { var result = BiliTool.GetResultFromUri(_detail.redirect_url); videoId = 0; _currentPartId = 0; if (result.Type == UriType.Bangumi) { throw new InvalidDataException(result.Param); } } TitleBlock.Text = detail.title; ToolTipService.SetToolTip(TitleBlock, _detail.title); videoId = _detail.aid; bvId = _detail.bvid; PlayCountBlock.Text = AppTool.GetNumberAbbreviation(_detail.stat.view); DanmakuCountBlock.Text = AppTool.GetNumberAbbreviation(_detail.stat.danmaku); RepostButton.Text = AppTool.GetNumberAbbreviation(_detail.stat.share); CommentButton.Text = AppTool.GetNumberAbbreviation(_detail.stat.reply); BVBlock.Text = _detail.bvid; AVBlock.Text = _detail.aid.ToString(); DescriptionBlock.Text = _detail.desc; LikeButton.Text = AppTool.GetNumberAbbreviation(_detail.stat.like); CoinButton.Text = AppTool.GetNumberAbbreviation(_detail.stat.coin); FavoriteButton.Text = AppTool.GetNumberAbbreviation(_detail.stat.favorite); PublishBlock.Text = AppTool.GetReadDateString(_detail.pubdate); UPAvatar.ProfilePicture = string.IsNullOrEmpty(_detail.owner.face) ? null : new BitmapImage(new Uri(_detail.owner.face + "@50w.jpg")) { DecodePixelWidth = 40 }; UPNameBlock.Text = _detail.owner.name; if (_detail.pages != null) { _detail.pages.ForEach(p => VideoPartCollection.Add(p)); PartGridView.SelectedIndex = 0; } PartContainer.Visibility = _detail.pages.Count > 1 ? Visibility.Visible : Visibility.Collapsed; if (_detail.tag != null && _detail.tag.Count > 0) { TagGridView.Visibility = Visibility.Visible; _detail.tag.ForEach(p => TagCollection.Add(p)); } else { TagGridView.Visibility = Visibility.Collapsed; } if (_detail.staff != null && _detail.staff.Count > 0) { _detail.staff.ForEach(p => StaffCollection.Add(p)); SingleUserContainer.Visibility = Visibility.Collapsed; StaffContainer.Visibility = Visibility.Visible; } else { StaffContainer.Visibility = Visibility.Collapsed; SingleUserContainer.Visibility = Visibility.Visible; } if (_detail.req_user != null) { LikeButton.IsCheck = _detail.req_user.like != 0; CoinButton.IsCheck = _detail.req_user.coin != 0; FavoriteButton.IsCheck = _detail.req_user.favorite != 0; } await MyVideoPlayer.Init(_detail, _currentPartId); CheckLikeHoldState(); }
protected override async Task OnInitializedAsync() { secilenVideo = await VideoService.GetVideoById(1); }
public IActionResult VideoDetail(string id) { //详情 long vid = 0; if (!long.TryParse(id, out vid)) { return(Redirect("/error")); } var videoDetailKey = $"VideoDetail_{id}"; var videoDetail = _redisService.Get <VideoDetail>(videoDetailKey); if (videoDetail == null) { var video = _videoService.GetVideo(vid); if (video == null) { return(Redirect("/error")); } var videoSource = _videoService.GetVideoSourceByVideo(video.Id); if (videoSource == null) { return(Redirect("/error")); } videoDetail = new VideoDetail() { Video = video, VideoSource = videoSource }; var cacheTime = 60;//1小时 var type = VideoCommonService.GetVideoType(video.Classify); if (type == "电影" || type == "伦理") { cacheTime = 60 * 24 * 3;//3天 } _redisService.Set(videoDetailKey, videoDetail, cacheTime); } var videoType = VideoCommonService.GetVideoType(videoDetail.Video.Classify);; //热播 var hotListKey = "VideoHotList_" + videoType; if (!_memoryCache.TryGetValue(hotListKey, out List <VideoRank> hotList)) { hotList = new List <VideoRank>(); var dayRanking = _videoRankingService.GetDayRankingByType(videoType, 1, 10);//日榜前10 var dayRankingList = _videoService.GetVideoList(dayRanking.Select(x => Convert.ToInt64(x.Key))); dayRanking.ForEach(item => { var dayRankingItem = dayRankingList.FirstOrDefault(x => x.Id == Convert.ToInt64(item.Key)); if (dayRankingItem != null) { hotList.Add(ConvertVideoToVideoRank(dayRankingItem, item.Value)); } }); _memoryCache.Set(hotListKey, hotList, new DateTimeOffset(DateTime.Now.AddMinutes(5)));//5分钟 } ViewData["VideoDetail_HotList"] = hotList; //推荐 var recommendKey = "VideoRecommendList_" + videoType; if (!_memoryCache.TryGetValue(recommendKey, out List <VideoRank> recommendList)) { recommendList = new List <VideoRank>(); var weekRanking = _videoRankingService.GetWeekRankingByType(videoType, 1, 4);//周榜前4 var weekRankingList = _videoService.GetVideoList(weekRanking.Select(x => Convert.ToInt64(x.Key))); weekRanking.ForEach(item => { var weekRankingItem = weekRankingList.FirstOrDefault(x => x.Id == Convert.ToInt64(item.Key)); if (weekRankingItem != null) { recommendList.Add(ConvertVideoToVideoRank(weekRankingItem, item.Value)); } }); _memoryCache.Set(recommendKey, recommendList, new DateTimeOffset(DateTime.Now.AddHours(1)));//1小时 } ViewData["VideoDetail_RecommendList"] = recommendList; //统计 _videoRankingService.AccessStatistics(id, videoDetail.Video.Classify); ViewData["VideoDetail_VideoType"] = videoType; return(View(videoDetail)); }
public async Task <OperationResponse <VideoDetail> > CreateAsync(VideoDetail model) { // Validation var similarVideo = await _unitOfWork.Videos.GetByTitleAsync(model.Title); if (similarVideo != null) { return new OperationResponse <VideoDetail> { IsSuccess = false, Message = "Failed to create the video, another one has the same title" } } ; if (model.ThumpFile == null) { return new OperationResponse <VideoDetail> { IsSuccess = false, Message = "Thump image is required" } } ; string thumpUrl = string.Empty; try { thumpUrl = await _storage.SaveFileAsync(model.ThumpFile, "Uploads"); } catch (BadImageFormatException) { return(new OperationResponse <VideoDetail> { IsSuccess = false, Message = "Please upload a valid image file" }); } var video = new Video { Category = model.Category, Description = model.Description, Likes = 0, Views = 0, Privacy = model.Privacy, ThumpUrl = thumpUrl, Title = model.Title, VideoUrl = model.VideoUrl, PublishingDate = model.PublishingDate, Tags = model.Tags?.Select(t => new Tag { Name = t, }).ToList(), }; await _unitOfWork.Videos.CreateAsync(video); await _unitOfWork.CommitChangesAsync(_identity.UserId); model.Id = video.Id; model.ThumpFile = null; // TODO: Get the URL of the running API and replace the hardcoded one model.ThumpUrl = $"{_env.ApiUrl}/{thumpUrl}"; return(new OperationResponse <VideoDetail> { IsSuccess = true, Message = "Video has been created successfully!", Data = model }); }
private VideoDetail GetInfos(string vid, out string errorMsg) { errorMsg = string.Empty; var info_api = $"http://vv.video.qq.com/getinfo?otype=json&appver=3.2.19.333&platform=11&defnpayver=1&vid={vid}"; var info = HttpHelper.Get(info_api); var infoText = Util.Match(info, "QZOutputJson=(.*)").TrimEnd(';'); var infoJson = JsonConvert.DeserializeObject(infoText) as JObject; if (infoJson["msg"] != null) { errorMsg = (string)infoJson["msg"]; return(null); } var fn_pre = (string)infoJson["vl"]["vi"][0]["lnk"]; //名称 var title = (string)infoJson["vl"]["vi"][0]["ti"]; //文件名 var fn = (string)infoJson["vl"]["vi"][0]["fn"]; //文件类型 var type = Path.GetExtension(fn); var host = (string)infoJson["vl"]["vi"][0]["ul"]["ui"][0]["url"]; var seg_cnt = (int)infoJson["vl"]["vi"][0]["cl"]["fc"]; if (seg_cnt == 0) { seg_cnt = 1; } var streams = infoJson["fl"]["fi"]; //取最后一个 var stream = streams.LastOrDefault(); var quality = (string)stream["name"]; var definition = (string)stream["cname"]; definition = definition.Replace(";", ""); var part_format_id = (int)stream["id"]; var fs = (long)stream["fs"]; var partInfos = new List <VideoPart>(); //先根据fc判断是否有分片 var fc = (int)infoJson["vl"]["vi"][0]["cl"]["fc"]; if (fc == 0) { var id = (string)infoJson["vl"]["vi"][0]["cl"]["keyid"]; var format_id = id.Split('.')[1]; double.TryParse((string)infoJson["vl"]["vi"][0]["td"], out double duration); partInfos.Add(new VideoPart() { Index = 1, Id = format_id, Duration = duration, Name = fn }); } else { var ci = infoJson["vl"]["vi"][0]["cl"]["ci"]; foreach (var item in ci) { var index = (int)item["idx"]; double.TryParse((string)item["cd"], out double duration); var id = (string)item["keyid"]; partInfos.Add(new VideoPart() { Index = index, Id = id, Duration = duration, Name = $"{fn_pre}.p{part_format_id % 10000}.{index}.mp4" }); } } Parallel.ForEach(partInfos, part => { int tryCount = 2; var filename = part.Name; GetKeyInfo: var key_api = $"http://vv.video.qq.com/getkey?otype=json&platform=11&format={part_format_id}&vid={vid}&filename={filename}&appver=3.2.19.333"; var keyInfo = HttpHelper.Get(key_api); if (string.IsNullOrEmpty(keyInfo)) { if (tryCount <= 0) { part.Remark = "请求失败"; return; } tryCount--; Task.Delay(200); goto GetKeyInfo; } var keyText = Util.Match(keyInfo, "QZOutputJson=(.*)").TrimEnd(';'); var keyJson = JsonConvert.DeserializeObject(keyText) as JObject; if (string.IsNullOrEmpty((string)keyJson["key"])) { part.Remark = (string)keyJson["msg"]; return; } var vkey = (string)keyJson["key"]; var url = $"{host}{filename}?vkey={vkey}"; part.Url = url; }); var detail = new VideoDetail() { Site = SiteCode.qq.GetDescription(), Title = title, Type = type, Parts = partInfos.OrderBy(x => x.Index).ToList(), Definition = definition, Size = fs }; return(detail); }