예제 #1
0
파일: DidlBuilder.cs 프로젝트: leaty/Emby
        private void AddVideoResource(XmlWriter writer, IHasMediaSources video, string deviceId, Filter filter, string contentFeatures, StreamInfo streamInfo)
        {
            writer.WriteStartElement(string.Empty, "res", NS_DIDL);

            var url = streamInfo.ToDlnaUrl(_serverAddress, _accessToken);

            var mediaSource = streamInfo.MediaSource;

            if (mediaSource.RunTimeTicks.HasValue)
            {
                writer.WriteAttributeString("duration", TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value).ToString("c", _usCulture));
            }

            if (filter.Contains("res@size"))
            {
                if (streamInfo.IsDirectStream || streamInfo.EstimateContentLength)
                {
                    var size = streamInfo.TargetSize;

                    if (size.HasValue)
                    {
                        writer.WriteAttributeString("size", size.Value.ToString(_usCulture));
                    }
                }
            }

            var totalBitrate     = streamInfo.TargetTotalBitrate;
            var targetSampleRate = streamInfo.TargetAudioSampleRate;
            var targetChannels   = streamInfo.TargetAudioChannels;

            var targetWidth  = streamInfo.TargetWidth;
            var targetHeight = streamInfo.TargetHeight;

            if (targetChannels.HasValue)
            {
                writer.WriteAttributeString("nrAudioChannels", targetChannels.Value.ToString(_usCulture));
            }

            if (filter.Contains("res@resolution"))
            {
                if (targetWidth.HasValue && targetHeight.HasValue)
                {
                    writer.WriteAttributeString("resolution", string.Format("{0}x{1}", targetWidth.Value, targetHeight.Value));
                }
            }

            if (targetSampleRate.HasValue)
            {
                writer.WriteAttributeString("sampleFrequency", targetSampleRate.Value.ToString(_usCulture));
            }

            if (totalBitrate.HasValue)
            {
                writer.WriteAttributeString("bitrate", totalBitrate.Value.ToString(_usCulture));
            }

            var mediaProfile = _profile.GetVideoMediaProfile(streamInfo.Container,
                                                             streamInfo.TargetAudioCodec,
                                                             streamInfo.TargetVideoCodec,
                                                             streamInfo.TargetAudioBitrate,
                                                             targetWidth,
                                                             targetHeight,
                                                             streamInfo.TargetVideoBitDepth,
                                                             streamInfo.TargetVideoProfile,
                                                             streamInfo.TargetVideoLevel,
                                                             streamInfo.TargetFramerate,
                                                             streamInfo.TargetPacketLength,
                                                             streamInfo.TargetTimestamp,
                                                             streamInfo.IsTargetAnamorphic,
                                                             streamInfo.IsTargetInterlaced,
                                                             streamInfo.TargetRefFrames,
                                                             streamInfo.TargetVideoStreamCount,
                                                             streamInfo.TargetAudioStreamCount,
                                                             streamInfo.TargetVideoCodecTag,
                                                             streamInfo.IsTargetAVC);

            var filename = url.Substring(0, url.IndexOf('?'));

            var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType)
               ? GetMimeType(filename)
               : mediaProfile.MimeType;

            writer.WriteAttributeString("protocolInfo", String.Format(
                                            "http-get:*:{0}:{1}",
                                            mimeType,
                                            contentFeatures
                                            ));

            writer.WriteString(url);

            writer.WriteFullEndElement();
        }
예제 #2
0
        private void AddVideoResource(XmlElement container, Video video, string deviceId, Filter filter, string contentFeatures, StreamInfo streamInfo)
        {
            var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);

            var url = streamInfo.ToDlnaUrl(_serverAddress);

            res.InnerText = url;

            var mediaSource = streamInfo.MediaSource;

            if (mediaSource.RunTimeTicks.HasValue)
            {
                res.SetAttribute("duration", TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value).ToString("c", _usCulture));
            }

            if (filter.Contains("res@size"))
            {
                if (streamInfo.IsDirectStream || streamInfo.EstimateContentLength)
                {
                    var size = streamInfo.TargetSize;

                    if (size.HasValue)
                    {
                        res.SetAttribute("size", size.Value.ToString(_usCulture));
                    }
                }
            }

            var totalBitrate     = streamInfo.TargetTotalBitrate;
            var targetSampleRate = streamInfo.TargetAudioSampleRate;
            var targetChannels   = streamInfo.TargetAudioChannels;

            var targetWidth  = streamInfo.TargetWidth;
            var targetHeight = streamInfo.TargetHeight;

            if (targetChannels.HasValue)
            {
                res.SetAttribute("nrAudioChannels", targetChannels.Value.ToString(_usCulture));
            }

            if (filter.Contains("res@resolution"))
            {
                if (targetWidth.HasValue && targetHeight.HasValue)
                {
                    res.SetAttribute("resolution", string.Format("{0}x{1}", targetWidth.Value, targetHeight.Value));
                }
            }

            if (targetSampleRate.HasValue)
            {
                res.SetAttribute("sampleFrequency", targetSampleRate.Value.ToString(_usCulture));
            }

            if (totalBitrate.HasValue)
            {
                res.SetAttribute("bitrate", totalBitrate.Value.ToString(_usCulture));
            }

            var mediaProfile = _profile.GetVideoMediaProfile(streamInfo.Container,
                                                             streamInfo.AudioCodec,
                                                             streamInfo.VideoCodec,
                                                             streamInfo.TargetAudioBitrate,
                                                             targetChannels,
                                                             targetWidth,
                                                             targetHeight,
                                                             streamInfo.TargetVideoBitDepth,
                                                             streamInfo.TargetVideoBitrate,
                                                             streamInfo.TargetVideoProfile,
                                                             streamInfo.TargetVideoLevel,
                                                             streamInfo.TargetFramerate,
                                                             streamInfo.TargetPacketLength,
                                                             streamInfo.TargetTimestamp,
                                                             streamInfo.IsTargetAnamorphic);

            var filename = url.Substring(0, url.IndexOf('?'));

            var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType)
               ? MimeTypes.GetMimeType(filename)
               : mediaProfile.MimeType;

            res.SetAttribute("protocolInfo", String.Format(
                                 "http-get:*:{0}:{1}",
                                 mimeType,
                                 contentFeatures
                                 ));

            container.AppendChild(res);
        }
예제 #3
0
        private void AddVideoResource(XmlElement container, Video video, string deviceId, Filter filter)
        {
            var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);

            var sources = _dtoService.GetMediaSources(video);

            int?maxBitrateSetting = null;

            var streamInfo = new StreamBuilder().BuildVideoItem(new VideoOptions
            {
                ItemId       = video.Id.ToString("N"),
                MediaSources = sources,
                Profile      = _profile,
                DeviceId     = deviceId,
                MaxBitrate   = maxBitrateSetting
            });

            var url = streamInfo.ToDlnaUrl(_serverAddress);

            //res.AppendChild(container.OwnerDocument.CreateCDataSection(url));
            res.InnerText = url;

            var mediaSource = sources.First(i => string.Equals(i.Id, streamInfo.MediaSourceId));

            if (mediaSource.RunTimeTicks.HasValue)
            {
                res.SetAttribute("duration", TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value).ToString("c", _usCulture));
            }

            if (filter.Contains("res@size"))
            {
                if (streamInfo.IsDirectStream || streamInfo.EstimateContentLength)
                {
                    var size = streamInfo.TargetSize;

                    if (size.HasValue)
                    {
                        res.SetAttribute("size", size.Value.ToString(_usCulture));
                    }
                }
            }

            var totalBitrate     = streamInfo.TargetTotalBitrate;
            var targetSampleRate = streamInfo.TargetAudioSampleRate;
            var targetChannels   = streamInfo.TargetAudioChannels;

            var targetWidth  = streamInfo.TargetWidth;
            var targetHeight = streamInfo.TargetHeight;

            if (targetChannels.HasValue)
            {
                res.SetAttribute("nrAudioChannels", targetChannels.Value.ToString(_usCulture));
            }

            if (filter.Contains("res@resolution"))
            {
                if (targetWidth.HasValue && targetHeight.HasValue)
                {
                    res.SetAttribute("resolution", string.Format("{0}x{1}", targetWidth.Value, targetHeight.Value));
                }
            }

            if (targetSampleRate.HasValue)
            {
                res.SetAttribute("sampleFrequency", targetSampleRate.Value.ToString(_usCulture));
            }

            if (totalBitrate.HasValue)
            {
                res.SetAttribute("bitrate", totalBitrate.Value.ToString(_usCulture));
            }

            var mediaProfile = _profile.GetVideoMediaProfile(streamInfo.Container,
                                                             streamInfo.AudioCodec,
                                                             streamInfo.VideoCodec,
                                                             streamInfo.TargetAudioBitrate,
                                                             targetChannels,
                                                             targetWidth,
                                                             targetHeight,
                                                             streamInfo.TargetVideoBitDepth,
                                                             streamInfo.TargetVideoBitrate,
                                                             streamInfo.TargetVideoProfile,
                                                             streamInfo.TargetVideoLevel,
                                                             streamInfo.TargetFramerate,
                                                             streamInfo.TargetPacketLength,
                                                             streamInfo.TargetTimestamp);

            var filename = url.Substring(0, url.IndexOf('?'));

            var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType)
               ? MimeTypes.GetMimeType(filename)
               : mediaProfile.MimeType;

            var contentFeatures = new ContentFeatureBuilder(_profile).BuildVideoHeader(streamInfo.Container,
                                                                                       streamInfo.VideoCodec,
                                                                                       streamInfo.AudioCodec,
                                                                                       targetWidth,
                                                                                       targetHeight,
                                                                                       streamInfo.TargetVideoBitDepth,
                                                                                       streamInfo.TargetVideoBitrate,
                                                                                       streamInfo.TargetAudioChannels,
                                                                                       streamInfo.TargetAudioBitrate,
                                                                                       streamInfo.TargetTimestamp,
                                                                                       streamInfo.IsDirectStream,
                                                                                       streamInfo.RunTimeTicks,
                                                                                       streamInfo.TargetVideoProfile,
                                                                                       streamInfo.TargetVideoLevel,
                                                                                       streamInfo.TargetFramerate,
                                                                                       streamInfo.TargetPacketLength,
                                                                                       streamInfo.TranscodeSeekInfo);

            res.SetAttribute("protocolInfo", String.Format(
                                 "http-get:*:{0}:{1}",
                                 mimeType,
                                 contentFeatures
                                 ));

            container.AppendChild(res);
        }
        /// <summary>
        /// Builds a video header.
        /// </summary>
        /// <param name="profile">A <see cref="DeviceProfile"/>.</param>
        /// <param name="container">The container.</param>
        /// <param name="videoCodec">The video codec.</param>
        /// <param name="audioCodec">The audio codec.</param>
        /// <param name="width">Optional. The width.</param>
        /// <param name="height">Optional. The height.</param>
        /// <param name="bitDepth">Optional. The bit depth.</param>
        /// <param name="videoBitrate">Optional. The video bitrate.</param>
        /// <param name="timestamp">Optional. A <see cref="TransportStreamTimestamp"/>.</param>
        /// <param name="isDirectStream">True if the stream is playable by directStream.</param>
        /// <param name="runtimeTicks">Optional. Runtime ticks.</param>
        /// <param name="videoProfile">The video profile.</param>
        /// <param name="videoLevel">Optional. The video level.</param>
        /// <param name="videoFramerate">Optional. The video framerate.</param>
        /// <param name="packetLength">Optional. The packet length.</param>
        /// <param name="transcodeSeekInfo">The <see cref="TranscodeSeekInfo"/>.</param>
        /// <param name="isAnamorphic">Optional. True, if anamorphic.</param>
        /// <param name="isInterlaced">Optional. True, if interlaced.</param>
        /// <param name="refFrames">Optional. The number of reference frames.</param>
        /// <param name="numVideoStreams">Optional. The number of video streams.</param>
        /// <param name="numAudioStreams">Optional. The number of audio streams.</param>
        /// <param name="videoCodecTag">The video codec tag.</param>
        /// <param name="isAvc">True is AVC.</param>
        /// <returns>A list containing the video information.</returns>
        public static List <string> BuildVideoHeader(
            DeviceProfile profile,
            string container,
            string?videoCodec,
            string?audioCodec,
            int?width,
            int?height,
            int?bitDepth,
            int?videoBitrate,
            TransportStreamTimestamp timestamp,
            bool isDirectStream,
            long?runtimeTicks,
            string?videoProfile,
            double?videoLevel,
            float?videoFramerate,
            int?packetLength,
            TranscodeSeekInfo transcodeSeekInfo,
            bool?isAnamorphic,
            bool?isInterlaced,
            int?refFrames,
            int?numVideoStreams,
            int?numAudioStreams,
            string?videoCodecTag,
            bool?isAvc)
        {
            if (profile == null)
            {
                throw new ArgumentNullException(nameof(profile));
            }

            // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
            string orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks > 0, isDirectStream, transcodeSeekInfo);

            // 0 = native, 1 = transcoded
            string orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";

            var flagValue = DlnaFlags.StreamingTransferMode |
                            DlnaFlags.BackgroundTransferMode |
                            DlnaFlags.InteractiveTransferMode |
                            DlnaFlags.DlnaV15;

            if (isDirectStream)
            {
                flagValue |= DlnaFlags.ByteBasedSeek;
            }
            else if (runtimeTicks.HasValue)
            {
                flagValue |= DlnaFlags.TimeBasedSeek;
            }

            string dlnaflags = string.Format(CultureInfo.InvariantCulture, ";DLNA.ORG_FLAGS={0}", DlnaMaps.FlagsToString(flagValue));

            var mediaProfile = profile.GetVideoMediaProfile(
                container,
                audioCodec,
                videoCodec,
                width,
                height,
                bitDepth,
                videoBitrate,
                videoProfile,
                videoLevel,
                videoFramerate,
                packetLength,
                timestamp,
                isAnamorphic,
                isInterlaced,
                refFrames,
                numVideoStreams,
                numAudioStreams,
                videoCodecTag,
                isAvc);

            var orgPnValues = new List <string>();

            if (mediaProfile != null && !string.IsNullOrEmpty(mediaProfile.OrgPn))
            {
                orgPnValues.AddRange(mediaProfile.OrgPn.Split(',', StringSplitOptions.RemoveEmptyEntries));
            }
            else
            {
                foreach (var s in GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp))
                {
                    orgPnValues.Add(s.ToString());
                    break;
                }
            }

            var contentFeatureList = new List <string>();

            foreach (string orgPn in orgPnValues)
            {
                if (string.IsNullOrEmpty(orgPn))
                {
                    contentFeatureList.Add(orgOp.TrimStart(';') + orgCi + dlnaflags);
                }
                else
                {
                    contentFeatureList.Add("DLNA.ORG_PN=" + orgPn + orgCi + dlnaflags);
                }
            }

            if (orgPnValues.Count == 0)
            {
                contentFeatureList.Add(orgOp.TrimStart(';') + orgCi + dlnaflags);
            }

            return(contentFeatureList);
        }