コード例 #1
0
 public static bool FindCompatibleMime(EndPointProfile profile, List <string> resolvedList, ref string Mime)
 {
     foreach (MediaMimeMapping map in profile.MediaMimeMap.Values)
     {
         if (resolvedList.Contains(map.MappedMediaFormat) == true)
         {
             Mime = map.MIME;
             return(true);
         }
     }
     foreach (MediaMimeMapping map in profile.MediaMimeMap.Values)
     {
         if (string.IsNullOrEmpty(map.MIMEName) == false)
         {
             List <string> renamedMaps = new List <string>();
             renamedMaps.AddRange(map.MIMEName.Split(','));
             foreach (string submap in renamedMaps)
             {
                 if (resolvedList.Contains(submap) == true)
                 {
                     Mime = map.MIME;
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
コード例 #2
0
        public ProfileMediaItem(string clientId, EndPointProfile profile, bool live)
        {
            _clientId = clientId;

            Profile              = profile;
            LastUpdated          = DateTime.Now;
            TranscodingParameter = null;
            IsSegmented          = false;
            IsLive = live;
        }
コード例 #3
0
        public static async Task <WebStringResult> ProcessAsync(IOwinContext context, string identifier, string profileName, long startPosition)
        {
            if (identifier == null)
            {
                throw new BadRequestException("InitStream: identifier is null");
            }
            if (profileName == null)
            {
                throw new BadRequestException("InitStream: profileName is null");
            }

            StreamItem streamItem = await StreamControl.GetStreamItemAsync(identifier);

            if (streamItem == null)
            {
                throw new BadRequestException(string.Format("StartStream: Unknown identifier: {0}", identifier));
            }

            // Prefer getting profile by name
            EndPointProfile profile = ProfileManager.Profiles.Values.FirstOrDefault(p => p.Name == profileName);

            // If no ptofile with the specified name, see if there's one with a matching id
            if (profile == null && !ProfileManager.Profiles.TryGetValue(profileName, out profile))
            {
                throw new BadRequestException(string.Format("StartStream: Unknown profile: {0}", profileName));
            }

            streamItem.Profile = profile;
            // Seeking is not supported in live streams
            streamItem.StartPosition = streamItem.RequestedMediaItem is LiveTvMediaItem ? 0 : startPosition;

            Guid?userId = ResourceAccessUtils.GetUser(context);

            streamItem.TranscoderObject = new ProfileMediaItem(identifier, profile, streamItem.IsLive);
            await streamItem.TranscoderObject.Initialize(userId, streamItem.RequestedMediaItem, null);

            if (streamItem.TranscoderObject.TranscodingParameter is VideoTranscoding vt)
            {
                vt.HlsBaseUrl = string.Format("RetrieveStream?identifier={0}&hls=", identifier);
            }

            await StreamControl.StartStreamingAsync(identifier, startPosition);

            string filePostFix = "&file=media.ts";

            if (profile.MediaTranscoding?.VideoTargets?.Any(t => t.Target.VideoContainerType == VideoContainer.Hls) ?? false)
            {
                filePostFix = "&file=manifest.m3u8"; //Must be added for some clients to work (Android mostly)
            }
            string url = GetBaseStreamUrl.GetBaseStreamURL(context) + "/MPExtended/StreamingService/stream/RetrieveStream?identifier=" + identifier + filePostFix;

            return(new WebStringResult {
                Result = url
            });
        }
コード例 #4
0
        public static async Task LoadProfilesAsync(bool userProfiles)
        {
            try
            {
                string profileFile = FileUtils.BuildAssemblyRelativePath(PROFILE_FILE);
                if (userProfiles)
                {
                    IPathManager pathManager = ServiceRegistration.Get <IPathManager>();
                    string       dataPath    = pathManager.GetPath("<CONFIG>");
                    profileFile = Path.Combine(dataPath, PROFILE_FILE);
                }
                else
                {
                    TranscodeProfileManager.ClearTranscodeProfiles(TRANSCODE_PROFILE_SECTION);
                }

                if (File.Exists(profileFile) == true)
                {
                    XmlTextReader   reader  = new XmlTextReader(profileFile);
                    EndPointProfile profile = null;
                    while (reader.Read())
                    {
                        if (reader.NodeType != XmlNodeType.Element && reader.NodeType != XmlNodeType.EndElement)
                        {
                            continue;
                        }
                        string nodeName = reader.Name;
                        #region Profile
                        if (nodeName == "Profile" && reader.NodeType == XmlNodeType.Element)
                        {
                            profile = new EndPointProfile();
                            while (reader.MoveToNextAttribute()) // Read the attributes.
                            {
                                if (reader.Name == "id")
                                {
                                    profile.ID = reader.ReadContentAsString();
                                }
                                else if (reader.Name == "name")
                                {
                                    profile.Name = reader.ReadContentAsString();
                                }
                                else if (reader.Name == "active")
                                {
                                    profile.Active = reader.ReadContentAsBoolean();
                                }
                                else if (reader.Name == "baseProfile")
                                {
                                    string parentProfileId = reader.ReadContentAsString();
                                    if (Profiles.ContainsKey(parentProfileId) == true)
                                    {
                                        profile.UpnpDevice.DeviceInformation.FriendlyName     = Profiles[parentProfileId].UpnpDevice.DeviceInformation.FriendlyName;
                                        profile.UpnpDevice.DeviceInformation.Manufacturer     = Profiles[parentProfileId].UpnpDevice.DeviceInformation.Manufacturer;
                                        profile.UpnpDevice.DeviceInformation.ManufacturerURL  = Profiles[parentProfileId].UpnpDevice.DeviceInformation.ManufacturerURL;
                                        profile.UpnpDevice.DeviceInformation.ModelDescription = Profiles[parentProfileId].UpnpDevice.DeviceInformation.ModelDescription;
                                        profile.UpnpDevice.DeviceInformation.ModelName        = Profiles[parentProfileId].UpnpDevice.DeviceInformation.ModelName;
                                        profile.UpnpDevice.DeviceInformation.ModelNumber      = Profiles[parentProfileId].UpnpDevice.DeviceInformation.ModelNumber;
                                        profile.UpnpDevice.DeviceInformation.ModelURL         = Profiles[parentProfileId].UpnpDevice.DeviceInformation.ModelURL;
                                        profile.UpnpDevice.DeviceInformation.SerialNumber     = Profiles[parentProfileId].UpnpDevice.DeviceInformation.SerialNumber;
                                        profile.UpnpDevice.DeviceInformation.UPC = Profiles[parentProfileId].UpnpDevice.DeviceInformation.UPC;
                                        profile.UpnpDevice.AdditionalElements    = Profiles[parentProfileId].UpnpDevice.AdditionalElements;

                                        profile.DirectoryContentBuilder = Profiles[parentProfileId].DirectoryContentBuilder;
                                        profile.ResourceAccessHandler   = Profiles[parentProfileId].ResourceAccessHandler;
                                        profile.DirectoryContentFilter  = Profiles[parentProfileId].DirectoryContentFilter;
                                        profile.ProtocolInfo            = Profiles[parentProfileId].ProtocolInfo;

                                        profile.Settings.Thumbnails.MaxHeight = Profiles[parentProfileId].Settings.Thumbnails.MaxHeight;
                                        profile.Settings.Thumbnails.MaxWidth  = Profiles[parentProfileId].Settings.Thumbnails.MaxWidth;
                                        profile.Settings.Thumbnails.Delivery  = Profiles[parentProfileId].Settings.Thumbnails.Delivery;

                                        profile.Settings.Communication.AllowChunckedTransfer = Profiles[parentProfileId].Settings.Communication.AllowChunckedTransfer;
                                        profile.Settings.Communication.DefaultBufferSize     = Profiles[parentProfileId].Settings.Communication.DefaultBufferSize;
                                        profile.Settings.Communication.InitialBufferSize     = Profiles[parentProfileId].Settings.Communication.InitialBufferSize;

                                        profile.Settings.Metadata.Delivery = Profiles[parentProfileId].Settings.Metadata.Delivery;

                                        profile.MediaMimeMap = new Dictionary <string, MediaMimeMapping>(Profiles[parentProfileId].MediaMimeMap);
                                    }
                                }
                            }
                        }
                        #endregion Profile
                        else if (nodeName == "DLNAProtocolInfo" && reader.NodeType == XmlNodeType.Element)
                        {
                            profile.ProtocolInfo = (ProtocolInfoFormat)Enum.Parse(typeof(ProtocolInfoFormat), reader.ReadElementContentAsString(), true);
                        }
                        #region Detections
                        else if (nodeName == "Detections" && reader.NodeType == XmlNodeType.Element)
                        {
                            while (reader.Read())
                            {
                                if (reader.Name == "Detections" && reader.NodeType == XmlNodeType.EndElement)
                                {
                                    break;
                                }
                                if (reader.Name == "Detection" && reader.NodeType == XmlNodeType.Element)
                                {
                                    Detection detection = new Detection();
                                    while (reader.Read())
                                    {
                                        if (reader.Name == "Detection" && reader.NodeType == XmlNodeType.EndElement)
                                        {
                                            break;
                                        }
                                        if (reader.Name == "UPnPSearch")
                                        {
                                            while (reader.Read())
                                            {
                                                if (reader.Name == "UPnPSearch" && reader.NodeType == XmlNodeType.EndElement)
                                                {
                                                    break;
                                                }
                                                if (reader.Name == "FriendlyName" && reader.NodeType == XmlNodeType.Element)
                                                {
                                                    detection.UPnPSearch.FriendlyName = reader.ReadElementContentAsString();
                                                }
                                                else if (reader.Name == "ModelName" && reader.NodeType == XmlNodeType.Element)
                                                {
                                                    detection.UPnPSearch.ModelName = reader.ReadElementContentAsString();
                                                }
                                                else if (reader.Name == "ModelNumber" && reader.NodeType == XmlNodeType.Element)
                                                {
                                                    detection.UPnPSearch.ModelNumber = reader.ReadElementContentAsString();
                                                }
                                                else if (reader.Name == "ProductNumber" && reader.NodeType == XmlNodeType.Element)
                                                {
                                                    detection.UPnPSearch.ProductNumber = reader.ReadElementContentAsString();
                                                }
                                                else if (reader.Name == "Server" && reader.NodeType == XmlNodeType.Element)
                                                {
                                                    detection.UPnPSearch.Server = reader.ReadElementContentAsString();
                                                }
                                                else if (reader.Name == "Manufacturer" && reader.NodeType == XmlNodeType.Element)
                                                {
                                                    detection.UPnPSearch.Manufacturer = reader.ReadElementContentAsString();
                                                }
                                            }
                                        }
                                        else if (reader.Name == "HttpSearch")
                                        {
                                            while (reader.Read())
                                            {
                                                if (reader.Name == "HttpSearch" && reader.NodeType == XmlNodeType.EndElement)
                                                {
                                                    break;
                                                }
                                                if (reader.NodeType == XmlNodeType.Element)
                                                {
                                                    detection.HttpHeaders.Add(reader.Name, reader.ReadElementContentAsString());
                                                }
                                            }
                                        }
                                    }
                                    profile.Detections.Add(detection);
                                }
                            }
                        }
                        #endregion Detections
                        else if (nodeName == "DirectoryContentBuilder" && reader.NodeType == XmlNodeType.Element)
                        {
                            profile.DirectoryContentBuilder = (GenericDidlMessageBuilder.ContentBuilder)Enum.Parse(typeof(GenericDidlMessageBuilder.ContentBuilder), reader.ReadElementContentAsString(), true);
                        }
                        else if (nodeName == "ResourceAccessProtocol" && reader.NodeType == XmlNodeType.Element)
                        {
                            profile.ResourceAccessHandler = (GenericAccessProtocol.ResourceAccessProtocol)Enum.Parse(typeof(GenericAccessProtocol.ResourceAccessProtocol), reader.ReadElementContentAsString(), true);
                        }
                        else if (nodeName == "DirectoryContentFilter" && reader.NodeType == XmlNodeType.Element)
                        {
                            profile.DirectoryContentFilter = (GenericContentDirectoryFilter.ContentFilter)Enum.Parse(typeof(GenericContentDirectoryFilter.ContentFilter), reader.ReadElementContentAsString(), true);
                        }
                        #region UPNPDeviceDescription
                        else if (nodeName == "UPNPDeviceDescription" && reader.NodeType == XmlNodeType.Element)
                        {
                            while (reader.Read())
                            {
                                if (reader.Name == "UPNPDeviceDescription" && reader.NodeType == XmlNodeType.EndElement)
                                {
                                    break;
                                }
                                if (reader.Name == "FriendlyName")
                                {
                                    profile.UpnpDevice.DeviceInformation.FriendlyName = reader.ReadElementContentAsString().Replace("{computerName}", Dns.GetHostName());
                                }
                                else if (reader.Name == "Manufacturer")
                                {
                                    profile.UpnpDevice.DeviceInformation.Manufacturer = reader.ReadElementContentAsString();
                                }
                                else if (reader.Name == "ManufacturerURL")
                                {
                                    profile.UpnpDevice.DeviceInformation.ManufacturerURL = reader.ReadElementContentAsString();
                                }
                                else if (reader.Name == "ModelDescription")
                                {
                                    profile.UpnpDevice.DeviceInformation.ModelDescription = reader.ReadElementContentAsString();
                                }
                                else if (reader.Name == "ModelName")
                                {
                                    profile.UpnpDevice.DeviceInformation.ModelName = reader.ReadElementContentAsString();
                                }
                                else if (reader.Name == "ModelNumber")
                                {
                                    profile.UpnpDevice.DeviceInformation.ModelNumber = reader.ReadElementContentAsString();
                                }
                                else if (reader.Name == "ModelURL")
                                {
                                    profile.UpnpDevice.DeviceInformation.ModelURL = reader.ReadElementContentAsString();
                                }
                                else if (reader.Name == "AdditionalElements")
                                {
                                    profile.UpnpDevice.AdditionalElements = reader.ReadElementContentAsString().Replace("\t", "").Replace("\r", "").Replace("\n", "").Replace("  ", "").Trim();
                                }
                            }
                        }
                        #endregion UPNPDeviceDescription
                        else if (nodeName == "DLNAMediaFormats" && reader.NodeType == XmlNodeType.Element)
                        {
                            while (reader.Read())
                            {
                                if (reader.Name == "DLNAMediaFormats" && reader.NodeType == XmlNodeType.EndElement)
                                {
                                    break;
                                }
                                if (reader.Name == "MediaFormat" && reader.NodeType == XmlNodeType.Element)
                                {
                                    MediaMimeMapping map = new MediaMimeMapping();
                                    while (reader.MoveToNextAttribute()) // Read the attributes.
                                    {
                                        if (reader.Name == "mime")
                                        {
                                            map.MIME = reader.ReadContentAsString();
                                        }
                                        else if (reader.Name == "name")
                                        {
                                            map.MIMEName = reader.ReadContentAsString();
                                        }
                                    }
                                    reader.Read();
                                    map.MappedMediaFormat = reader.Value;
                                    //Overwrite any inherited media map
                                    if (profile.MediaMimeMap.ContainsKey(map.MappedMediaFormat))
                                    {
                                        profile.MediaMimeMap[map.MappedMediaFormat] = map;
                                    }
                                    else
                                    {
                                        profile.MediaMimeMap.Add(map.MappedMediaFormat, map);
                                    }
                                }
                            }
                        }
                        else if (nodeName == "Settings" && reader.NodeType == XmlNodeType.Element)
                        {
                            while (reader.Read())
                            {
                                if (reader.Name == "Settings" && reader.NodeType == XmlNodeType.EndElement)
                                {
                                    break;
                                }
                                else if (reader.Name == "Thumbnails" && reader.NodeType == XmlNodeType.Element)
                                {
                                    while (reader.MoveToNextAttribute()) // Read the attributes.
                                    {
                                        if (reader.Name == "maxWidth")
                                        {
                                            profile.Settings.Thumbnails.MaxWidth = reader.ReadContentAsInt();
                                        }
                                        else if (reader.Name == "maxHeight")
                                        {
                                            profile.Settings.Thumbnails.MaxHeight = reader.ReadContentAsInt();
                                        }
                                        else if (reader.Name == "delivery")
                                        {
                                            profile.Settings.Thumbnails.Delivery = (ThumbnailDelivery)Enum.Parse(typeof(ThumbnailDelivery), reader.ReadContentAsString(), true);
                                        }
                                    }
                                }
                                else if (reader.Name == "Communication" && reader.NodeType == XmlNodeType.Element)
                                {
                                    while (reader.MoveToNextAttribute()) // Read the attributes.
                                    {
                                        if (reader.Name == "allowChunckedTransfer")
                                        {
                                            profile.Settings.Communication.AllowChunckedTransfer = reader.ReadContentAsBoolean();
                                        }
                                        else if (reader.Name == "initialBufferSize")
                                        {
                                            profile.Settings.Communication.InitialBufferSize = reader.ReadContentAsLong();
                                        }
                                        else if (reader.Name == "defaultBufferSize")
                                        {
                                            profile.Settings.Communication.DefaultBufferSize = reader.ReadContentAsInt();
                                        }
                                    }
                                }
                                else if (reader.Name == "Metadata" && reader.NodeType == XmlNodeType.Element)
                                {
                                    while (reader.MoveToNextAttribute()) // Read the attributes.
                                    {
                                        if (reader.Name == "delivery")
                                        {
                                            profile.Settings.Metadata.Delivery = (MetadataDelivery)Enum.Parse(typeof(MetadataDelivery), reader.ReadContentAsString(), true);
                                        }
                                    }
                                }
                            }
                        }
                        else if (nodeName == "Profile" && reader.NodeType == XmlNodeType.EndElement)
                        {
                            if (Profiles.ContainsKey(profile.ID))
                            {
                                //User profiles can override defaults
                                if (userProfiles == true)
                                {
                                    profile.Name = profile.Name + " [User]";
                                }
                                Profiles[profile.ID] = profile;
                            }
                            else
                            {
                                Profiles.TryAdd(profile.ID, profile);
                            }
                        }
                    }
                    reader.Close();

                    await TranscodeProfileManager.LoadTranscodeProfilesAsync(TRANSCODE_PROFILE_SECTION, profileFile);
                }

                ProfileLinkSettings.Profiles = Profiles.ToDictionary(p => p.Key, p => p.Value.Name);
            }
            catch (Exception e)
            {
                Logger.Info("DlnaMediaServer: Exception reading profiles (Text: '{0}')", e.Message);
            }
        }
コード例 #5
0
        protected static async Task SendByteRangeAsync(IOwinContext context, Stream resourceStream, ProfileMediaItem item, EndPointProfile profile, Range range, bool onlyHeaders, bool partialResource, TransferMode mediaTransferMode)
        {
            if (range.From > 0 && range.From == range.To)
            {
                context.Response.StatusCode    = (int)HttpStatusCode.RequestedRangeNotSatisfiable;
                context.Response.ContentLength = 0;
                context.Response.ContentType   = null;
                return;
            }
            long length = range.Length;

            if (item.IsSegmented == false && item.IsTranscoding == true)
            {
                length = GetStreamSize(item);
            }
            else
            {
                length = resourceStream.Length;
            }
            Range fileRange = ConvertToFileRange(range, item, length);

            if (fileRange.From < 0 || length <= fileRange.From)
            {
                context.Response.StatusCode    = (int)HttpStatusCode.RequestedRangeNotSatisfiable;
                context.Response.ContentLength = 0;
                context.Response.ContentType   = null;
                return;
            }
            if (partialResource == false && await WaitForMinimumFileSizeAsync(resourceStream, fileRange.From) == false)
            {
                context.Response.StatusCode    = (int)HttpStatusCode.RequestedRangeNotSatisfiable;
                context.Response.ContentLength = 0;
                context.Response.ContentType   = null;
                return;
            }
            if (range.From > length || range.To > length)
            {
                range = fileRange;
            }

            context.Response.StatusCode = (int)HttpStatusCode.PartialContent;

            if (item.IsLive || range.Length == 0 ||
                (mediaTransferMode == TransferMode.Streaming && context.Request.Protocol == "HTTP/1.1" && profile.Settings.Communication.AllowChunckedTransfer))
            {
                context.Response.Headers["Content-Range"] = $"bytes {range.From}-";
                context.Response.ContentLength            = null;
            }
            else if (length <= 0)
            {
                context.Response.Headers["Content-Range"] = $"bytes {range.From}-{range.To - 1}";
                context.Response.ContentLength            = range.Length;
            }
            else
            {
                context.Response.Headers["Content-Range"] = $"bytes {range.From}-{range.To - 1}/{length}";
                context.Response.ContentLength            = range.Length;
            }
            if (item.IsLive == false)
            {
                context.Response.Headers["X-Content-Duration"] = Convert.ToDouble(item.Metadata.Duration).ToString("0.00", CultureInfo.InvariantCulture);
                context.Response.Headers["Content-Duration"]   = Convert.ToDouble(item.Metadata.Duration).ToString("0.00", CultureInfo.InvariantCulture);
            }

            await SendAsync(context, resourceStream, item, profile, onlyHeaders, partialResource, fileRange);
        }
コード例 #6
0
        protected static async Task SendAsync(IOwinContext context, Stream resourceStream, ProfileMediaItem item, EndPointProfile profile, bool onlyHeaders, bool partialResource, Range byteRange)
        {
            if (onlyHeaders)
            {
                return;
            }

            bool clientDisconnected = false;
            Guid streamID           = item.StartStreaming();

            if (streamID == Guid.Empty)
            {
                Logger.Error("BaseSendData: Unable to start stream");
                return;
            }
            try
            {
                if (context.Response.ContentLength == 0)
                {
                    //Not allowed to have a content length of zero
                    context.Response.ContentLength = null;
                }
                Logger.Debug("BaseSendData: Sending chunked: {0}", context.Response.ContentLength == null);
                string clientID   = context.Request.RemoteIpAddress;
                int    bufferSize = profile.Settings.Communication.DefaultBufferSize;
                if (bufferSize <= 0)
                {
                    bufferSize = 1500;
                }
                byte[] buffer = new byte[bufferSize];
                int    bytesRead;
                long   count       = 0;
                bool   isStream    = false;
                long   waitForSize = 0;
                if (byteRange.Length == 0 || (byteRange.Length > 0 && byteRange.Length >= profile.Settings.Communication.InitialBufferSize))
                {
                    waitForSize = profile.Settings.Communication.InitialBufferSize;
                }
                if (partialResource == false)
                {
                    if (waitForSize < byteRange.From)
                    {
                        waitForSize = byteRange.From;
                    }
                }
                if (await WaitForMinimumFileSizeAsync(resourceStream, waitForSize) == false)
                {
                    Logger.Error("BaseSendData: Unable to send stream because of invalid length: {0} ({1} required)", resourceStream.Length, waitForSize);
                    return;
                }

                long start = 0;
                if (partialResource == false)
                {
                    start = byteRange.From;
                }
                if (resourceStream.CanSeek)
                {
                    resourceStream.Seek(start, SeekOrigin.Begin);
                }
                long length = byteRange.Length;
                if (length <= 0 || item.IsLive || (item.IsSegmented == false && item.IsTranscoding == true))
                {
                    isStream = true;
                }
                int emptyCount = 0;
                while (item.IsStreamActive(streamID))
                {
                    if (isStream)
                    {
                        if (resourceStream.CanSeek)
                        {
                            length = resourceStream.Length - count;
                        }
                        else
                        {
                            length = bufferSize; //Keep stream alive
                        }
                    }
                    bytesRead = await resourceStream.ReadAsync(buffer, 0, length > bufferSize?bufferSize : (int)length);

                    count += bytesRead;

                    if (bytesRead > 0)
                    {
                        emptyCount = 0;
                        try
                        {
                            //Send fetched bytes
                            await context.Response.WriteAsync(buffer, 0, bytesRead, SendDataCancellation.Token);
                        }
                        catch (Exception)
                        {
                            // Client disconnected
                            Logger.Debug("BaseSendData: Connection lost after {0} bytes", count);
                            clientDisconnected = true;
                            break;
                        }
                        length -= bytesRead;

                        if (isStream == false && length <= 0)
                        {
                            //All bytes in the requested range sent
                            break;
                        }
                    }
                    else
                    {
                        emptyCount++;
                        if (emptyCount > 2)
                        {
                            Logger.Debug("BaseSendData: Buffer underrun delay");
                            await Task.Delay(100);
                        }
                        if (emptyCount > 10)
                        {
                            //Stream is not getting any bigger
                            break;
                        }
                    }

                    if (resourceStream.CanSeek)
                    {
                        if (item.IsTranscoding == false && resourceStream.Position == resourceStream.Length)
                        {
                            //No more data will be available
                            break;
                        }
                    }
                }
            }
            finally
            {
                item.StopStreaming(streamID);

                if (clientDisconnected || item.IsSegmented == false)
                {
                    if (clientDisconnected == false)
                    {
                        //Everything sent to client so presume watched
                        if (item.IsLive == false)
                        {
                            Guid?         userId  = ResourceAccessUtils.GetUser(context);
                            IMediaLibrary library = ServiceRegistration.Get <IMediaLibrary>();
                            if (library != null && userId.HasValue)
                            {
                                library.NotifyUserPlayback(userId.Value, item.MediaItemId, 100, true);
                            }
                        }
                    }
                }
                Logger.Debug("BaseSendData: Sending complete");
            }
        }
コード例 #7
0
        protected static async Task SendWholeFileAsync(IOwinContext context, Stream resourceStream, ProfileMediaItem item, EndPointProfile profile, bool onlyHeaders, bool partialResource, TransferMode mediaTransferMode)
        {
            if (await WaitForMinimumFileSizeAsync(resourceStream, 1) == false)
            {
                context.Response.StatusCode    = (int)HttpStatusCode.RequestedRangeNotSatisfiable;
                context.Response.ContentLength = 0;
                context.Response.ContentType   = null;
                Logger.Debug("BaseSendData: Sending headers: " + string.Join(";", context.Response.Headers.Select(x => x.Key + "=" + x.Value).ToArray()));
                return;
            }

            long length = GetStreamSize(item);

            if (resourceStream.CanSeek == true && (item.IsTranscoding == false || item.IsSegmented == true))
            {
                length = resourceStream.Length;
            }

            if (resourceStream.CanSeek == false && context.Request.Protocol == "HTTP/1.1" && profile.Settings.Communication.AllowChunckedTransfer)
            {
                context.Response.StatusCode    = (int)HttpStatusCode.PartialContent;
                context.Response.ContentLength = null;
            }
            else
            {
                context.Response.StatusCode    = (int)HttpStatusCode.OK;
                context.Response.ContentLength = length;
            }

            Range byteRange = new Range(0, context.Response.ContentLength ?? 0);

            await SendAsync(context, resourceStream, item, profile, onlyHeaders, partialResource, byteRange);
        }
コード例 #8
0
        public static async Task <WebStringResult> ProcessAsync(IOwinContext context, string identifier, string profileName, long startPosition, int audioId = -1, int subtitleId = -1)
        {
            if (identifier == null)
            {
                throw new BadRequestException("StartStreamWithStreamSelection: identifier is null");
            }
            if (profileName == null)
            {
                throw new BadRequestException("StartStreamWithStreamSelection: profileName is null");
            }

            EndPointProfile        profile       = null;
            List <EndPointProfile> namedProfiles = ProfileManager.Profiles.Where(x => x.Value.Name == profileName).Select(namedProfile => namedProfile.Value).ToList();

            if (namedProfiles.Count > 0)
            {
                profile = namedProfiles[0];
            }
            else if (ProfileManager.Profiles.ContainsKey(profileName))
            {
                profile = ProfileManager.Profiles[profileName];
            }
            if (profile == null)
            {
                throw new BadRequestException(string.Format("StartStreamWithStreamSelection: unknown profile: {0}", profileName));
            }

            StreamItem streamItem = await StreamControl.GetStreamItemAsync(identifier);

            if (streamItem == null)
            {
                throw new BadRequestException(string.Format("StartStreamWithStreamSelection: unknown identifier: {0}", identifier));
            }

            streamItem.Profile       = profile;
            streamItem.StartPosition = startPosition;
            if (streamItem.RequestedMediaItem is LiveTvMediaItem)
            {
                streamItem.StartPosition = 0;
            }

            Guid?userId = ResourceAccessUtils.GetUser(context);

            streamItem.TranscoderObject = new ProfileMediaItem(identifier, profile, streamItem.IsLive);
            await streamItem.TranscoderObject.Initialize(userId, streamItem.RequestedMediaItem, audioId >= 0?audioId : (int?)null, subtitleId);

            if ((streamItem.TranscoderObject.TranscodingParameter is VideoTranscoding vt))
            {
                vt.HlsBaseUrl = string.Format("RetrieveStream?identifier={0}&hls=", identifier);
            }

            await StreamControl.StartStreamingAsync(identifier, startPosition);

            string filePostFix = "&file=media.ts";

            if (profile.MediaTranscoding != null && profile.MediaTranscoding.VideoTargets != null)
            {
                foreach (var target in profile.MediaTranscoding.VideoTargets)
                {
                    if (target.Target.VideoContainerType == VideoContainer.Hls)
                    {
                        filePostFix = "&file=manifest.m3u8"; //Must be added for some clients to work (Android mostly)
                        break;
                    }
                }
            }

            string url = GetBaseStreamUrl.GetBaseStreamURL(context) + "/MPExtended/StreamingService/stream/RetrieveStream?identifier=" + identifier + filePostFix;

            return(new WebStringResult {
                Result = url
            });
        }
コード例 #9
0
        public static void LoadProfiles(bool userProfiles)
        {
            try
            {
                string profileFile = FileUtils.BuildAssemblyRelativePath(PROFILE_FILE_NAME);
                if (userProfiles)
                {
                    IPathManager pathManager = ServiceRegistration.Get <IPathManager>();
                    string       dataPath    = pathManager.GetPath("<CONFIG>");
                    profileFile = Path.Combine(dataPath, PROFILE_FILE_NAME);
                }
                else
                {
                    TranscodeProfileManager.ClearTranscodeProfiles(TRANSCODE_PROFILE_SECTION);
                }

                if (File.Exists(profileFile) == true)
                {
                    XmlTextReader   reader  = new XmlTextReader(profileFile);
                    EndPointProfile profile = null;
                    while (reader.Read())
                    {
                        if (reader.NodeType != XmlNodeType.Element && reader.NodeType != XmlNodeType.EndElement)
                        {
                            continue;
                        }
                        string nodeName = reader.Name;
                        #region Profile
                        if (nodeName == "Profile" && reader.NodeType == XmlNodeType.Element)
                        {
                            profile = new EndPointProfile();
                            while (reader.MoveToNextAttribute()) // Read the attributes.
                            {
                                if (reader.Name == "id")
                                {
                                    profile.ID = reader.ReadContentAsString();
                                }
                                else if (reader.Name == "name")
                                {
                                    profile.Name = reader.ReadContentAsString();
                                }
                                else if (reader.Name == "active")
                                {
                                    profile.Active = reader.ReadContentAsBoolean();
                                }
                                else if (reader.Name == "baseProfile")
                                {
                                    string parentProfileId = reader.ReadContentAsString();
                                    if (Profiles.ContainsKey(parentProfileId) == true)
                                    {
                                        Logger.Info("ProfileManager: Profile: {0}, ParentProfile: {1}, ParentTargets: {2}", profile.Name, parentProfileId, string.Join(", ", Profiles[parentProfileId].Targets));
                                        profile.Targets = new List <string>(Profiles[parentProfileId].Targets);

                                        profile.Settings.Thumbnails.MaxHeight = Profiles[parentProfileId].Settings.Thumbnails.MaxHeight;
                                        profile.Settings.Thumbnails.MaxWidth  = Profiles[parentProfileId].Settings.Thumbnails.MaxWidth;
                                        profile.Settings.Thumbnails.Delivery  = Profiles[parentProfileId].Settings.Thumbnails.Delivery;

                                        profile.Settings.Communication.AllowChunckedTransfer = Profiles[parentProfileId].Settings.Communication.AllowChunckedTransfer;
                                        profile.Settings.Communication.DefaultBufferSize     = Profiles[parentProfileId].Settings.Communication.DefaultBufferSize;
                                        profile.Settings.Communication.InitialBufferSize     = Profiles[parentProfileId].Settings.Communication.InitialBufferSize;

                                        profile.Settings.Metadata.Delivery = Profiles[parentProfileId].Settings.Metadata.Delivery;

                                        profile.MediaMimeMap = new Dictionary <string, MediaMimeMapping>(Profiles[parentProfileId].MediaMimeMap);
                                    }
                                }
                            }
                        }
                        #endregion Profile
                        #region Targets
                        else if (nodeName == "Targets" && reader.NodeType == XmlNodeType.Element)
                        {
                            while (reader.Read())
                            {
                                if (reader.Name == "Targets" && reader.NodeType == XmlNodeType.EndElement)
                                {
                                    break;
                                }
                                if (reader.Name == "Target" && reader.NodeType == XmlNodeType.Element)
                                {
                                    profile.Targets.Add(reader.ReadElementContentAsString().Trim());
                                }
                            }
                        }
                        #endregion Targets

                        else if (nodeName == "WebMediaFormats" && reader.NodeType == XmlNodeType.Element)
                        {
                            while (reader.Read())
                            {
                                if (reader.Name == "WebMediaFormats" && reader.NodeType == XmlNodeType.EndElement)
                                {
                                    break;
                                }
                                if (reader.Name == "MediaFormat" && reader.NodeType == XmlNodeType.Element)
                                {
                                    MediaMimeMapping map = new MediaMimeMapping();
                                    while (reader.MoveToNextAttribute()) // Read the attributes.
                                    {
                                        if (reader.Name == "mime")
                                        {
                                            map.MIME = reader.ReadContentAsString();
                                        }
                                        else if (reader.Name == "name")
                                        {
                                            map.MIMEName = reader.ReadContentAsString();
                                        }
                                    }
                                    reader.Read();
                                    map.MappedMediaFormat = reader.Value;
                                    //Overwrite any inherited media map
                                    if (profile.MediaMimeMap.ContainsKey(map.MappedMediaFormat))
                                    {
                                        profile.MediaMimeMap[map.MappedMediaFormat] = map;
                                    }
                                    else
                                    {
                                        profile.MediaMimeMap.Add(map.MappedMediaFormat, map);
                                    }
                                }
                            }
                        }
                        else if (nodeName == "Settings" && reader.NodeType == XmlNodeType.Element)
                        {
                            while (reader.Read())
                            {
                                if (reader.Name == "Settings" && reader.NodeType == XmlNodeType.EndElement)
                                {
                                    break;
                                }
                                else if (reader.Name == "Thumbnails" && reader.NodeType == XmlNodeType.Element)
                                {
                                    while (reader.MoveToNextAttribute()) // Read the attributes.
                                    {
                                        if (reader.Name == "maxWidth")
                                        {
                                            profile.Settings.Thumbnails.MaxWidth = reader.ReadContentAsInt();
                                        }
                                        else if (reader.Name == "maxHeight")
                                        {
                                            profile.Settings.Thumbnails.MaxHeight = reader.ReadContentAsInt();
                                        }
                                        else if (reader.Name == "delivery")
                                        {
                                            profile.Settings.Thumbnails.Delivery = (ThumbnailDelivery)Enum.Parse(typeof(ThumbnailDelivery), reader.ReadContentAsString(), true);
                                        }
                                    }
                                }
                                else if (reader.Name == "Communication" && reader.NodeType == XmlNodeType.Element)
                                {
                                    while (reader.MoveToNextAttribute()) // Read the attributes.
                                    {
                                        if (reader.Name == "allowChunckedTransfer")
                                        {
                                            profile.Settings.Communication.AllowChunckedTransfer = reader.ReadContentAsBoolean();
                                        }
                                        else if (reader.Name == "initialBufferSize")
                                        {
                                            profile.Settings.Communication.InitialBufferSize = reader.ReadContentAsLong();
                                        }
                                        else if (reader.Name == "defaultBufferSize")
                                        {
                                            profile.Settings.Communication.DefaultBufferSize = reader.ReadContentAsInt();
                                        }
                                    }
                                }
                                else if (reader.Name == "Metadata" && reader.NodeType == XmlNodeType.Element)
                                {
                                    while (reader.MoveToNextAttribute()) // Read the attributes.
                                    {
                                        if (reader.Name == "delivery")
                                        {
                                            profile.Settings.Metadata.Delivery = (MetadataDelivery)Enum.Parse(typeof(MetadataDelivery), reader.ReadContentAsString(), true);
                                        }
                                    }
                                }
                            }
                        }
                        else if (nodeName == "Profile" && reader.NodeType == XmlNodeType.EndElement)
                        {
                            if (Profiles.ContainsKey(profile.ID))
                            {
                                //User profiles can override defaults
                                if (userProfiles == true)
                                {
                                    profile.Name = profile.Name + " [User]";
                                }
                                Profiles[profile.ID] = profile;
                            }
                            else
                            {
                                Profiles.Add(profile.ID, profile);
                            }
                        }
                    }
                    reader.Close();

                    TranscodeProfileManager.LoadTranscodeProfilesAsync(TRANSCODE_PROFILE_SECTION, profileFile);
                }
            }
            catch (Exception e)
            {
                Logger.Info("MP2Extended: Exception reading profiles (Text: '{0}')", e.Message);
            }
        }
コード例 #10
0
        public static Task <WebResolution> ProcessAsync(IOwinContext context, WebMediaType type, int?provider, string itemId, int?offset, string profileName)
        {
            if (itemId == null)
            {
                throw new BadRequestException("GetStreamSize: itemId is null");
            }
            if (profileName == null)
            {
                throw new BadRequestException("GetStreamSize: profileName is null");
            }

            ISet <Guid> necessaryMIATypes = new HashSet <Guid>();

            necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
            necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID);
            necessaryMIATypes.Add(ImporterAspect.ASPECT_ID);

            ISet <Guid> optionalMIATypes = new HashSet <Guid>();

            optionalMIATypes.Add(VideoAspect.ASPECT_ID);
            optionalMIATypes.Add(VideoStreamAspect.ASPECT_ID);
            optionalMIATypes.Add(VideoAudioStreamAspect.ASPECT_ID);
            optionalMIATypes.Add(ImageAspect.ASPECT_ID);

            var item = MediaLibraryAccess.GetMediaItemById(context, itemId, necessaryMIATypes, optionalMIATypes);

            if (item == null)
            {
                throw new NotFoundException(String.Format("GetStreamSize: No MediaItem found with id: {0}", itemId));
            }

            EndPointProfile        profile       = null;
            List <EndPointProfile> namedProfiles = ProfileManager.Profiles.Where(x => x.Value.Name == profileName).Select(namedProfile => namedProfile.Value).ToList();

            if (namedProfiles.Count > 0)
            {
                profile = namedProfiles[0];
            }
            else if (ProfileManager.Profiles.ContainsKey(profileName))
            {
                profile = ProfileManager.Profiles[profileName];
            }
            if (profile == null)
            {
                throw new BadRequestException(string.Format("GetStreamSize: unknown profile: {0}", profileName));
            }

            var target = new ProfileMediaItem(Guid.NewGuid().ToString(), profile, false);

            var output = new WebResolution();

            if (target.IsImage)
            {
                output.Height = target.Image.Height ?? 0;
                output.Width  = target.Image.Width ?? 0;
            }
            else if (target.IsVideo)
            {
                output.Height = target.Image.Height ?? 0;
                output.Width  = target.Image.Width ?? 0;
            }

            return(Task.FromResult(output));
        }