Exemple #1
0
        /// <summary>
        /// validate the new packet and add it the video packets
        /// </summary>
        /// <param name="newPacketToAdd"></param>
        public void AddPacketFile(YoutubeMediaPacket newPacketToAdd)
        {
            // if the video is stored or being stored don't add any packets
            if (this.VideoBeingStored || VideoStored)
            {
                return;
            }

            Debug.WriteLine("adding " + newPacketToAdd.VideoPacketType.ToString() + " Packet : " + newPacketToAdd.Range.Start + "-" + newPacketToAdd.Range.End);

            // check if the new coming packets are having a different video quality than exiting packets
            // if so .. remove them and consider all of them as a gabs to fill in the final step
            if (newPacketToAdd.VideoPacketType == YoutubeMediaPacketType.Video &&
                newPacketToAdd.PacketMediaFileDataInfo.VerticalResolution.HasValue &&
                newPacketToAdd.PacketMediaFileDataInfo.VerticalResolution != this.Video.CurrentVideoVerticalRosolution)    // to make sure not considering the first packet as a gab ... because _currentHigherVideoVerticalRosolution starts by 0
            {
                this.Video.CurrentVideoVerticalRosolution = newPacketToAdd.PacketMediaFileDataInfo.VerticalResolution.Value;
                // truncating all previous packets
                _truncateVideoPackets(newPacketToAdd.VideoPacketType);
            }

            // this prevent packets from being intersecting
            // intersecting packets are packets that has it range intersect with the previous packets
            // main cause of these packets is the inturrupting video ads that rebuffer a part of stream suddenly
            bool newComingIntersectingPacketAlreadyStored = this.Video.Packets.ToList().Any(x => x.Range.End + 1 > newPacketToAdd.Range.Start &&
                                                                                            x.VideoPacketType == newPacketToAdd.VideoPacketType);

            if (!newComingIntersectingPacketAlreadyStored)
            {
                // i will add the new packet if it's range start is greater than all stored packets range's end
                this.Video.Packets.Add(newPacketToAdd);
            }
            _checkIfLastPacket(newPacketToAdd);
        }
Exemple #2
0
        private async Task <YoutubeMediaPacket> _fillGab(YoutubeRequestURL packetRequestURL, Range lostRange, YoutubeMediaPacketType type)
        {
            packetRequestURL.RequestPath.QueryString.SetValue("range", $"{lostRange.Start}-{lostRange.End}");
            var requestableURL = packetRequestURL.ToRequestableURL();

            // debugging
            YTrackLogger.Log("\nfilling broken range  for type " + type + " : " + lostRange.ToString() + " from : " + requestableURL);

            long httpSegmentSize = packetRequestURL.RequestPath.QueryString.HasValue("ratebypass") && packetRequestURL.RequestPath.QueryString.GetValue("ratebypass") == "yes"
                ? (long)lostRange.Length
                : 9_898_989;
            YoutubeMediaPacket packet;


            using (SegmentedHttpStream segmentedHttpStream = new SegmentedHttpStream(_client, requestableURL, (long)lostRange.Length, httpSegmentSize))
            {
                try
                {
                    string tmpFileName = Path.GetTempFileName();
                    using (Stream outputStream = new FileStream(tmpFileName, FileMode.Append))
                    {
                        IProgress <double> progressPercentage = new Progress <double>(b => packetDownloadProgressChanged(b));
                        await segmentedHttpStream.CopyToStreamAsync(outputStream, progressPercentage);
                    }
                    // no need to check whether the packetRequestURL is a valid requist URL
                    // because we requested it anyway
                    packet = new YoutubeMediaPacket(type, packetRequestURL, tmpFileName);
                    OnPacketDownloadCompleted?.Invoke(this, packet);
                }
                catch (Exception e)
                {
                    // two exception may be thrown
                    // WebException if something went wrong when fetch the new packets
                    // IOException if something went wrong when writing the packet file to disk
                    // I'll raise PacketDownloadExceptionThrown and re-throw exception
                    if (e is WebException)
                    {
                        _onGabPacketDownloadExceptionThrown?.Invoke(this, new PacketDownloadExceptionEventArgumanets()
                        {
                            Exception = e as WebException,
                            FailedPacketRequestURL = packetRequestURL,
                            Range = lostRange
                        });
                    }

                    // re-throw the error to the caller
                    Helpers.YTrackLogger.Log("Failed to download Packet : " + e.Message + "\n\n" + e.StackTrace);
                    throw;
                }
            }
            return(packet);
        }
Exemple #3
0
        private void _checkIfLastPacket(YoutubeMediaPacket packet)
        {
            // Get the last packet added to videos packets and the audios packets
            var lastVideoPacketAdded = _getTheLastAddedMediaPacket(YoutubeMediaPacketType.Video);
            var lastAudioPacketAdded = _getTheLastAddedMediaPacket(YoutubeMediaPacketType.Audio);

            // if the video does not recieve audio or video packet then don't proceed
            if (lastVideoPacketAdded == null || lastAudioPacketAdded == null)
            {
                return;
            }

            // if the packet is the last packet from the video stream proceed
            if (_doesLastAudioAndVideoPacketsRecieved())
            {
                // now I'll raise OnYoutubeLastPacketRecieved
                OnYoutubeLastPacketRecieved?.Invoke(this, packet);
            }
        }
Exemple #4
0
        private async Task _handleYoutubePacket(SessionEventArgs session)
        {
            // check if the packet in session is Audio or Video
            YoutubeMediaPacketType PacketType = _parseMediaPacketType(session.HttpClient.Response.Headers.Headers["Content-Type"].Value);

            // if content type is not video nor audio cancel it
            if (PacketType == YoutubeMediaPacketType.Unknown)
            {
                return;
            }

            var requestURL = requestURLFromSession(session);

            // making sure that the packet is valid to parse
            if (!YoutubeMediaPacket.IsValidYoutubeRequestURL(requestURL))
            {
                return;
            }

            byte[] bodyBytes = await session.GetResponseBody();

            var newPacket = new YoutubeMediaPacket(PacketType, requestURL, bodyBytes);

            // if videos list contains a video with the same fingerprint append the packet to it
            // otherwise create another video and add new packet to
            bool isVideoAddedBefore = this.VideosManagers.Any(x => x.Video.VideoFingerPrint == newPacket.VideoFingerPrint);

            if (!isVideoAddedBefore)
            {
                var newVideo        = new YoutubeVideo(newPacket.VideoFingerPrint);
                var newVideoManager = new YoutubeVideoManager(newVideo, _client);
                VideosManagers.Add(newVideoManager);
                newVideoManager.OnYoutubeLastPacketRecieved += videoLastPacketRecieved;
                newVideoManager.OnYoutubeStored             += NewVideoManager_OnYoutubeStored;
                newVideoManager.AddPacketFile(newPacket);
            }
            else
            {
                var packetVideo = VideosManagers.Where(x => x.Video.VideoFingerPrint == newPacket.VideoFingerPrint).FirstOrDefault();
                packetVideo.AddPacketFile(newPacket);
            }
        }
Exemple #5
0
 private void _insertGabPacket(YoutubeMediaPacket packetToInsert)
 {
     lock (this.Video.Packets)
     {
         // gab is the first packet
         if (packetToInsert.Range.Start == 0)
         {
             this.Video.Packets.Insert(0, packetToInsert);
         }
         // gab is the last packet
         else if (packetToInsert.Range.End + 1 == packetToInsert.OverAllLength)
         {
             this.Video.Packets.Insert(this.Video.Packets.Count - 1, packetToInsert);
         }
         // gab is in the middle of the video packets
         else
         {
             // see where the previous packet is and add it after
             int previousPacketIndex = this.Video.Packets.FindIndex(x => (x.Range.End + 1) == packetToInsert.Range.Start);
             this.Video.Packets.Insert(++previousPacketIndex, packetToInsert);
         }
     }
 }
Exemple #6
0
        private void videoLastPacketRecieved(object sender, YoutubeMediaPacket lastPacket)
        {
            YoutubeVideoManager videoManager = sender as YoutubeVideoManager;

            OnNewVideoLastPacketRecieved?.Invoke(videoManager);
        }