private IEnumerable <MediaStream> GetMediaStreams(ChannelMediaInfo info) { var list = new List <MediaStream>(); if (!string.IsNullOrWhiteSpace(info.VideoCodec) && !string.IsNullOrWhiteSpace(info.AudioCodec)) { list.Add(new MediaStream { Type = MediaStreamType.Video, Width = info.Width, RealFrameRate = info.Framerate, Profile = info.VideoProfile, Level = info.VideoLevel, Index = -1, Height = info.Height, Codec = info.VideoCodec, BitRate = info.VideoBitrate, AverageFrameRate = info.Framerate }); list.Add(new MediaStream { Type = MediaStreamType.Audio, Index = -1, Codec = info.AudioCodec, BitRate = info.AudioBitrate, Channels = info.AudioChannels, SampleRate = info.AudioSampleRate }); } return(list); }
private IEnumerable<MediaStream> GetMediaStreams(ChannelMediaInfo info) { var list = new List<MediaStream>(); if (!string.IsNullOrWhiteSpace(info.VideoCodec) && !string.IsNullOrWhiteSpace(info.AudioCodec)) { list.Add(new MediaStream { Type = MediaStreamType.Video, Width = info.Width, RealFrameRate = info.Framerate, Profile = info.VideoProfile, Level = info.VideoLevel, Index = -1, Height = info.Height, Codec = info.VideoCodec, BitRate = info.VideoBitrate, AverageFrameRate = info.Framerate }); list.Add(new MediaStream { Type = MediaStreamType.Audio, Index = -1, Codec = info.AudioCodec, BitRate = info.AudioBitrate, Channels = info.AudioChannels, SampleRate = info.AudioSampleRate }); } return list; }
private void Sanitize(ChannelMediaInfo info) { // Clean some bad data coming from providers if (info.AudioBitrate.HasValue && info.AudioBitrate <= 0) { info.AudioBitrate = null; } if (info.VideoBitrate.HasValue && info.VideoBitrate <= 0) { info.VideoBitrate = null; } if (info.AudioChannels.HasValue && info.AudioChannels <= 0) { info.AudioChannels = null; } if (info.Framerate.HasValue && info.Framerate <= 0) { info.Framerate = null; } if (info.Width.HasValue && info.Width <= 0) { info.Width = null; } if (info.Height.HasValue && info.Height <= 0) { info.Height = null; } if (info.AudioSampleRate.HasValue && info.AudioSampleRate <= 0) { info.AudioSampleRate = null; } if (info.VideoLevel.HasValue && info.VideoLevel <= 0) { info.VideoLevel = null; } }
public async Task<IEnumerable<ChannelMediaInfo>> GetChannelItemMediaInfo(string id, CancellationToken cancellationToken) { var items = new List<ChannelMediaInfo>(); using (var streaminfo = await _httpClient.Get(string.Format("http://www.svtplay.se{0}?output=json", id.ToLower()), cancellationToken)) { var response = _jsonSerializer.DeserializeFromStream<SvtPlay.Entities.SvtPlayResponse>(streaminfo); var mediasource = response.video.videoReferences.FirstOrDefault(r => r.playerType == "ios"); var info = new ChannelMediaInfo { Path = mediasource.url, RunTimeTicks = TimeSpan.FromSeconds(response.video.materialLength).Ticks }; items.Add(info); } return items; }
private MediaSourceInfo GetMediaSource(IChannelMediaItem item, ChannelMediaInfo info) { var id = info.Path.GetMD5().ToString("N"); var source = new MediaSourceInfo { MediaStreams = GetMediaStreams(info).ToList(), Container = info.Container, Protocol = info.Protocol, Path = info.Path, RequiredHttpHeaders = info.RequiredHttpHeaders, RunTimeTicks = item.RunTimeTicks, Name = id, Id = id }; return source; }
private ChannelMediaInfo GetMediaInfo(TrailerInfo info, bool isHd) { var mediaInfo = new ChannelMediaInfo { Path = info.TrailerUrl, Width = isHd ? 1280 : 720, Height = isHd ? 720 : 480, Container = (Path.GetExtension(info.TrailerUrl) ?? string.Empty).TrimStart('.'), AudioCodec = AudioCodec.AAC, VideoCodec = VideoCodec.H264, AudioChannels = 2, VideoBitrate = isHd ? 11000000 : 1000000, AudioBitrate = isHd ? 128000 : 80000, AudioSampleRate = 44100, Framerate = (float)23.976, VideoProfile = isHd ? "high" : "main", VideoLevel = isHd ? (float)3.1 : 3, SupportsDirectPlay = false }; mediaInfo.RequiredHttpHeaders.Add("User-Agent", "QuickTime/7.7.4"); return mediaInfo; }
private void AttachMediaStreamInfo(StreamState state, ChannelMediaInfo mediaInfo, VideoStreamRequest videoRequest, string requestedUrl) { var mediaSource = mediaInfo.ToMediaSource(); state.InputProtocol = mediaSource.Protocol; state.MediaPath = mediaSource.Path; state.RunTimeTicks = mediaSource.RunTimeTicks; state.RemoteHttpHeaders = mediaSource.RequiredHttpHeaders; state.InputBitrate = mediaSource.Bitrate; state.InputFileSize = mediaSource.Size; state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate; AttachMediaStreamInfo(state, mediaSource.MediaStreams, videoRequest, requestedUrl); }
protected ChannelMediaInfo SetValues(ChannelMediaInfo info) { var url = info.Path; int? width = null; int? height = null; var profile = "main"; var level = (float)3.0; // These bitrate numbers are just a guess to try and facilitate direct streaming if (url.IndexOf("1080", StringComparison.OrdinalIgnoreCase) != -1) { width = 1920; height = 1080; info.VideoBitrate = url.IndexOf("apple", StringComparison.OrdinalIgnoreCase) == -1 ? 3000000 : 11000000; level = (float)3.1; if (url.IndexOf("apple", StringComparison.OrdinalIgnoreCase) != -1) { profile = "high"; } } else if (url.IndexOf("720", StringComparison.OrdinalIgnoreCase) != -1) { width = 1280; height = 720; info.VideoBitrate = 1200000; } else if (url.IndexOf("480", StringComparison.OrdinalIgnoreCase) != -1) { width = 720; height = 480; info.VideoBitrate = 1000000; } else if (url.IndexOf("360", StringComparison.OrdinalIgnoreCase) != -1) { width = 640; height = 360; info.VideoBitrate = 1000000; } else { info.VideoBitrate = 3000000; } info.Height = height; info.Width = width; info.VideoCodec = VideoCodec.H264; info.AudioCodec = AudioCodec.AAC; info.AudioBitrate = 128000; info.AudioChannels = 2; info.AudioSampleRate = 44100; info.VideoProfile = profile; info.VideoLevel = level; info.Container = (Path.GetExtension(url) ?? string.Empty).TrimStart('.'); return info; }
private async Task TestMediaInfo(ChannelMediaInfo item, ListingResults results, CancellationToken cancellationToken) { var key = item.Path; if (string.IsNullOrEmpty(key)) { return; } ListingResult result; if (results.TestResults.TryGetValue(key, out result)) { // Was validated recently if (result.IsValid && (DateTime.UtcNow - result.DateTested).TotalDays <= 30) { return; } // Already known to be bad if (!result.IsValid) { return; } } var options = new HttpRequestOptions { Url = item.Path, CancellationToken = cancellationToken, BufferContent = false }; foreach (var header in item.RequiredHttpHeaders) { options.RequestHeaders[header.Key] = header.Value; } var isOk = false; try { var response = await _httpClient.SendAsync(options, "HEAD").ConfigureAwait(false); try { if (response.ContentType.StartsWith("video", StringComparison.OrdinalIgnoreCase)) { isOk = true; } } finally { response.Content.Dispose(); } } catch (HttpException ex) { if (!ex.StatusCode.HasValue) { throw; } if (ex.StatusCode.Value != HttpStatusCode.NotFound && ex.StatusCode.Value != HttpStatusCode.Forbidden) { throw; } } results.TestResults[key] = new ListingResult { IsValid = isOk, DateTested = DateTime.UtcNow }; }
private bool Filter(ChannelMediaInfo item, ListingResults results) { var key = item.Path; if (string.IsNullOrEmpty(key)) { return false; } ListingResult result; if (results.TestResults.TryGetValue(key, out result)) { return result.IsValid; } // Should never get here. return false return false; }