Esempio n. 1
0
        /// <summary>
        /// Retrieve first feed from a URI asynchronously
        /// </summary>
        /// <param name="uri">URI</param>
        /// <returns>MediaInfo object that contains the informations of the first feed</returns>
        public Task<MediaInfo> RetrieveFirstFeedAsync(string uri)
        {
            return Task.Run(() =>
                {
                    SyndicationFeed feed;
                    using (var xmlReader = XmlReader.Create(uri))
                    {
                        feed = SyndicationFeed.Load(xmlReader);
                    }
                    var item = feed.Items.FirstOrDefault();
                    if (item == null)
                    {
                        return null;
                    }
                    var mediaInfo = new MediaInfo()
                    {
                        Author = item.Authors == null || !item.Authors.Any() ? null : item.Authors.First().Name,
                        Title = item.Title.Text,
                    };

                    if (item.Links != null)
                    {
                        var link = item.Links.FirstOrDefault(l => l.RelationshipType == "enclosure");
                        if (link != null)
                        {
                            mediaInfo.Uri = link.Uri.AbsoluteUri;
                            mediaInfo.Type = link.MediaType;
                        }
                    }
                    return mediaInfo;
                });
        }
Esempio n. 2
0
        /// <summary>
        /// Retrieve first feed from a URI asynchronously
        /// </summary>
        /// <param name="uri">URI</param>
        /// <returns>MediaInfo object that contains the informations of the first feed</returns>
        public async Task<MediaInfo> RetrieveFirstFeedAsync(string uri)
        {
            var syndicationFeed = await new Windows.Web.Syndication.SyndicationClient().RetrieveFeedAsync(new Uri(uri));
            var item = syndicationFeed.Items.FirstOrDefault();
            if (item == null)
            {
                return null;
            }
            var mediaInfo = new MediaInfo()
            {
                Author = item.Authors == null || !item.Authors.Any() ? null : item.Authors.First().Name,
                Title = item.Title.Text,
                Uri = item.ItemUri == null ? null : item.ItemUri.AbsoluteUri
            };

            if (item.Links != null)
            {
                var link = item.Links.FirstOrDefault(l => l.Relationship == "enclosure");
                if (link != null)
                {
                    mediaInfo.Uri = link.Uri.AbsoluteUri;
                    mediaInfo.Type = link.MediaType;
                }
            }
            return mediaInfo;
        }
        private async Task SetMimeType(HttpClient httpClient, MediaInfo mediaInfo)
        {
            if (!String.IsNullOrWhiteSpace(mediaInfo.Title) && !String.IsNullOrWhiteSpace(mediaInfo.Type))
            {
                return;
            }

            var mediaUri = new Uri(WebUtility.UrlDecode(mediaInfo.Uri).Trim());
            String mediaFilename;
            try { mediaFilename = UriUtility.GetFileName(mediaUri.AbsolutePath); }
            catch (Exception) { mediaFilename = null; }
            if (String.IsNullOrWhiteSpace(mediaInfo.Title))
            {
                mediaInfo.Title = mediaFilename;
            }

            if (String.IsNullOrWhiteSpace(mediaInfo.Type))
            {
                if (!String.IsNullOrWhiteSpace(mediaFilename))
                {
                    var extension = UriUtility.GetExtension(mediaFilename);
                    if (!String.IsNullOrWhiteSpace(extension))
                    {
                        extension = extension.Substring(1).ToLower();
                        var mimeType = MimeTypes.FirstOrDefault(mt => mt.Extensions.Any(ext => extension == ext));
                        if (mimeType != null)
                        {
                            mediaInfo.Type = mimeType.Type;
                            return;
                        }
                    }
                }

                var httpRequest = new HttpRequestMessage() { RequestUri = mediaUri, Method = HttpMethod.Head };
                try
                {
                    var contentType = (await httpClient.GetAsync(mediaUri).TimeoutAfter(5000)).Content.Headers.ContentType;
                    if (contentType != null)
                    {
                        mediaInfo.Type = contentType.MediaType;
                        return;
                    }
                }
                catch (Exception) { }

                mediaInfo.Type = "video/mp4";
            }
        }
        /// <summary>
        /// Play a media HTTP link to a media renderer
        /// </summary>
        /// <param name="mediaRenderer">media renderer</param>
        /// <param name="mediaInfo">informations about the media</param>
        /// <returns>Task</returns>
        public async Task Play(Device mediaRenderer, MediaInfo mediaInfo)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.ExpectContinue = false;

                mediaInfo = await CheckUri(httpClient, mediaInfo);

                var requestUri = new Uri(mediaRenderer.Services.First(service => service.ServiceType == "urn:schemas-upnp-org:service:AVTransport:1").ControlURL, UriKind.RelativeOrAbsolute);
                if (!requestUri.IsAbsoluteUri || requestUri.IsFile) // In Mono.Android, requestUri will not a relative uri but a file
                {
                    requestUri = new Uri(new Uri(mediaRenderer.URLBase), requestUri);
                }

                var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                    "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                        "<s:Body>" +
                            "{0}" +
                        "</s:Body>" +
                    "</s:Envelope>";

                var xmlContent = String.Format(xml, String.Format(
                    "<u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\">" +
                        "<InstanceID>0</InstanceID>" +
                        "<CurrentURI>{0}</CurrentURI>" +
                        "<CurrentURIMetaData>{1}</CurrentURIMetaData>" +
                    "</u:SetAVTransportURI>", mediaInfo.Uri,
                    String.Format(WebUtility.HtmlEncode(
                    "<DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:sec=\"http://www.sec.co.kr/\">" +
                        "<item id=\"f-0\" parentID=\"0\" restricted=\"1\">" +
                        (mediaInfo.Title == null ? String.Empty : "<dc:title>{3}</dc:title>") +
                        (mediaInfo.Author == null ? String.Empty : "<dc:creator>{4}</dc:creator>") +
                        "<upnp:class>object.item.{2}</upnp:class>" +
                        "<res protocolInfo=\"http-get:*:{1}:DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000\">{0}</res>" +
                        "</item>" +
                        "</DIDL-Lite>"), mediaInfo.Uri, mediaInfo.Type, GetMimeTypeUPnPClass(mediaInfo.Type), mediaInfo.Title, mediaInfo.Author)));

                var request = CreateContent("SetAVTransportURI", xmlContent);
                request.Headers.Add("transferMode.dlna.org", "Streaming");
                request.Headers.Add("contentFeatures.dlna.org", "DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000");
                var response = await httpClient.PostAsync(requestUri, request);
                if (response.IsSuccessStatusCode)
                {
                    xmlContent = String.Format(xml,
                        "<u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\">" +
                            "<InstanceID>0</InstanceID>" +
                            "<Speed>1</Speed>" +
                        "</u:Play>");

                    response = await httpClient.PostAsync(requestUri, CreateContent("Play", xmlContent));
                }
                else
                {
                    throw new Exception(response.ReasonPhrase);
                }
            }
        }
        private async Task<MediaInfo> CheckUri(HttpClient httpClient, MediaInfo mediaInfo)
        {
            var premiumLinkGenerators = PremiumLinkGenerators;
            if (premiumLinkGenerators != null)
            {
                string url = null;
                foreach (var premiumLinkGenerator in premiumLinkGenerators)
                {
                    if (premiumLinkGenerator.Enabled)
                    {
                        try
                        {
                            var premiumLink = await premiumLinkGenerator.Unrestrict(url ?? (url = WebUtility.UrlDecode(mediaInfo.Uri).Trim()));
                            if (premiumLink != null)
                            {
                                if (String.IsNullOrWhiteSpace(mediaInfo.Title))
                                {
                                    mediaInfo.Title = premiumLink.Title;
                                }
                                mediaInfo.Uri = premiumLink.MainLink;
                                break;
                            }
                        }
                        catch (NotSupportedException) { }
                    }
                }
            }

            await SetMimeType(httpClient, mediaInfo);

            var syndicationClient = SyndicationClient;
            if (syndicationClient != null)
            {
                var mediaType = mediaInfo.Type;
                if (mediaType == "application/rss+xml" || mediaType == "application/xml" || mediaType == "text/xml" || mediaType == "application/rdf+xml" ||
                    mediaType == "application/atom+xml" || mediaType == "application/xml")
                {
                    // Podcast
                    var item = await syndicationClient.RetrieveFirstFeedAsync(mediaInfo.Uri);
                    if (item != null)
                    {
                        mediaInfo = item;
                        await SetMimeType(httpClient, mediaInfo);
                    }
                }
            }

            mediaInfo.XmlEscape();
            return mediaInfo;
        }