Exemplo n.º 1
0
            public void Should_SetDesiredVideoCodec_When_ContentIsPadded_ForTransportStream()
            {
                var ffmpegProfile = new FFmpegProfile
                {
                    NormalizeResolution = true,
                    Resolution          = new Resolution {
                        Width = 1920, Height = 1080
                    },
                    NormalizeVideoCodec = false,
                    VideoCodec          = "testCodec"
                };

                // not anamorphic
                var version = new MediaVersion {
                    Width = 1918, Height = 1080, SampleAspectRatio = "1:1"
                };

                FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                    StreamingMode.TransportStream,
                    ffmpegProfile,
                    version,
                    DateTimeOffset.Now,
                    DateTimeOffset.Now);

                actual.ScaledSize.IsNone.Should().BeTrue();
                actual.PadToDesiredResolution.Should().BeTrue();
                actual.VideoCodec.Should().Be("testCodec");
            }
Exemplo n.º 2
0
            Should_SetVideoBufferSize_When_ContentIsCorrectSize_And_NormalizingWrongCodec_ForTransportStream()
            {
                var ffmpegProfile = new FFmpegProfile
                {
                    NormalizeResolution = true,
                    Resolution          = new Resolution {
                        Width = 1920, Height = 1080
                    },
                    NormalizeVideoCodec = true,
                    VideoBufferSize     = 2525
                };

                // not anamorphic
                var version = new MediaVersion
                {
                    Width = 1920, Height = 1080, SampleAspectRatio = "1:1", VideoCodec = "mpeg2video"
                };

                FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                    StreamingMode.TransportStream,
                    ffmpegProfile,
                    version,
                    DateTimeOffset.Now,
                    DateTimeOffset.Now);

                actual.ScaledSize.IsNone.Should().BeTrue();
                actual.PadToDesiredResolution.Should().BeFalse();
                actual.VideoBufferSize.IfNone(0).Should().Be(2525);
            }
Exemplo n.º 3
0
        public async Task <Either <BaseError, bool> > RefreshStatistics(string ffprobePath, MediaItem mediaItem)
        {
            try
            {
                string filePath = mediaItem switch
                {
                    Movie m => m.MediaVersions.Head().MediaFiles.Head().Path,
                    Episode e => e.MediaVersions.Head().MediaFiles.Head().Path,
                       _ => throw new ArgumentOutOfRangeException(nameof(mediaItem))
                };

                Either <BaseError, FFprobe> maybeProbe = await GetProbeOutput(ffprobePath, filePath);

                return(await maybeProbe.Match(
                           async ffprobe =>
                {
                    MediaVersion version = ProjectToMediaVersion(ffprobe);
                    bool result = await ApplyVersionUpdate(mediaItem, version, filePath);
                    return Right <BaseError, bool>(result);
                },
                           error => Task.FromResult(Left <BaseError, bool>(error))));
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "Failed to refresh statistics for media item {Id}", mediaItem.Id);
                return(BaseError.New(ex.Message));
            }
        }
Exemplo n.º 4
0
        public void Should_SetAudioDuration_With_CorrectFormat_ForTransportStream()
        {
            FFmpegProfile ffmpegProfile = TestProfile() with
            {
                AudioSampleRate = 48,
                AudioFormat     = FFmpegProfileAudioFormat.Ac3
            };

            var version = new MediaVersion
            {
                SampleAspectRatio = "1:1", Width = 1920, Height = 1080, Duration = TimeSpan.FromMinutes(5)
            }; // not pulled from here

            FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                StreamingMode.TransportStream,
                ffmpegProfile,
                version,
                new MediaStream(),
                new MediaStream {
                Codec = "ac3"
            },
                DateTimeOffset.Now,
                DateTimeOffset.Now,
                TimeSpan.Zero,
                TimeSpan.FromMinutes(2),
                false,
                None);

            actual.AudioDuration.IfNone(TimeSpan.MinValue).Should().Be(TimeSpan.FromMinutes(2));
        }
Exemplo n.º 5
0
        public void Should_SetCopyVideoFormat_When_ContentIsCorrectSize_ForHttpLiveStreamingDirect()
        {
            var ffmpegProfile = new FFmpegProfile
            {
                Resolution = new Resolution {
                    Width = 1920, Height = 1080
                },
                VideoFormat = FFmpegProfileVideoFormat.H264
            };

            // not anamorphic
            var version = new MediaVersion
            {
                Width = 1920, Height = 1080, SampleAspectRatio = "1:1"
            };

            FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                StreamingMode.HttpLiveStreamingDirect,
                ffmpegProfile,
                version,
                new MediaStream {
                Codec = "mpeg2video"
            },
                new MediaStream(),
                DateTimeOffset.Now,
                DateTimeOffset.Now,
                TimeSpan.Zero,
                TimeSpan.Zero,
                false,
                None);

            actual.ScaledSize.IsNone.Should().BeTrue();
            actual.PadToDesiredResolution.Should().BeFalse();
            actual.VideoFormat.Should().Be(FFmpegProfileVideoFormat.Copy);
        }
Exemplo n.º 6
0
        public void Should_SetVideoBufferSize_When_ContentIsCorrectSize_ForTransportStream()
        {
            var ffmpegProfile = new FFmpegProfile
            {
                Resolution = new Resolution {
                    Width = 1920, Height = 1080
                },
                VideoBufferSize = 2525
            };

            // not anamorphic
            var version = new MediaVersion
            {
                Width = 1920, Height = 1080, SampleAspectRatio = "1:1"
            };

            FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                StreamingMode.TransportStream,
                ffmpegProfile,
                version,
                new MediaStream {
                Codec = "mpeg2video"
            },
                new MediaStream(),
                DateTimeOffset.Now,
                DateTimeOffset.Now,
                TimeSpan.Zero,
                TimeSpan.Zero,
                false,
                None);

            actual.ScaledSize.IsNone.Should().BeTrue();
            actual.PadToDesiredResolution.Should().BeFalse();
            actual.VideoBufferSize.IfNone(0).Should().Be(2525);
        }
Exemplo n.º 7
0
        public void Should_NotPadToDesiredResolution_When_UnscaledContentIsUnderSized_ForHttpLiveStreaming()
        {
            FFmpegProfile ffmpegProfile = TestProfile() with
            {
                Resolution = new Resolution {
                    Width = 1920, Height = 1080
                }
            };

            // not anamorphic
            var version = new MediaVersion {
                Width = 1918, Height = 1080, SampleAspectRatio = "1:1"
            };

            FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                StreamingMode.HttpLiveStreamingDirect,
                ffmpegProfile,
                version,
                new MediaStream(),
                new MediaStream(),
                DateTimeOffset.Now,
                DateTimeOffset.Now,
                TimeSpan.Zero,
                TimeSpan.Zero,
                false,
                None);

            actual.ScaledSize.IsNone.Should().BeTrue();
            actual.PadToDesiredResolution.Should().BeFalse();
        }
Exemplo n.º 8
0
        public void Should_SetDesiredVideoFormat_When_ContentIsPadded_ForTransportStream()
        {
            var ffmpegProfile = new FFmpegProfile
            {
                Resolution = new Resolution {
                    Width = 1920, Height = 1080
                },
                VideoFormat = FFmpegProfileVideoFormat.H264
            };

            // not anamorphic
            var version = new MediaVersion {
                Width = 1918, Height = 1080, SampleAspectRatio = "1:1"
            };

            FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                StreamingMode.TransportStream,
                ffmpegProfile,
                version,
                new MediaStream(),
                new MediaStream(),
                DateTimeOffset.Now,
                DateTimeOffset.Now,
                TimeSpan.Zero,
                TimeSpan.Zero,
                false,
                None);

            actual.ScaledSize.IsNone.Should().BeTrue();
            actual.PadToDesiredResolution.Should().BeTrue();
            actual.VideoFormat.Should().Be(FFmpegProfileVideoFormat.H264);
        }
Exemplo n.º 9
0
        public void ShouldNot_SetScaledSize_When_ScaledSizeWouldEqualContentSize_ForTransportStream()
        {
            FFmpegProfile ffmpegProfile = TestProfile() with
            {
                Resolution = new Resolution {
                    Width = 1920, Height = 1080
                }
            };

            // not anamorphic
            var version = new MediaVersion {
                Width = 1918, Height = 1080, SampleAspectRatio = "1:1"
            };

            FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                StreamingMode.TransportStream,
                ffmpegProfile,
                version,
                new MediaStream(),
                new MediaStream(),
                DateTimeOffset.Now,
                DateTimeOffset.Now,
                TimeSpan.Zero,
                TimeSpan.Zero,
                false,
                None);

            actual.ScaledSize.IsNone.Should().BeTrue();
        }
Exemplo n.º 10
0
        public void Should_ScaleToEvenDimensions_ForTransportStream()
        {
            FFmpegProfile ffmpegProfile = TestProfile() with
            {
                Resolution = new Resolution {
                    Width = 1280, Height = 720
                }
            };

            var version = new MediaVersion {
                Width = 706, Height = 362, SampleAspectRatio = "32:27"
            };

            FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                StreamingMode.TransportStream,
                ffmpegProfile,
                version,
                new MediaStream(),
                new MediaStream(),
                DateTimeOffset.Now,
                DateTimeOffset.Now,
                TimeSpan.Zero,
                TimeSpan.Zero,
                false,
                None);

            IDisplaySize scaledSize = actual.ScaledSize.IfNone(new MediaVersion {
                Width = 0, Height = 0
            });

            scaledSize.Width.Should().Be(1280);
            scaledSize.Height.Should().Be(554);
            actual.PadToDesiredResolution.Should().BeTrue();
        }
    private async Task <string> GetPlayoutItemPath(PlayoutItem playoutItem)
    {
        MediaVersion version = playoutItem.MediaItem.GetHeadVersion();

        MediaFile file = version.MediaFiles.Head();
        string    path = file.Path;

        return(playoutItem.MediaItem switch
        {
            PlexMovie plexMovie => await _plexPathReplacementService.GetReplacementPlexPath(
                plexMovie.LibraryPathId,
                path),
            PlexEpisode plexEpisode => await _plexPathReplacementService.GetReplacementPlexPath(
                plexEpisode.LibraryPathId,
                path),
            JellyfinMovie jellyfinMovie => await _jellyfinPathReplacementService.GetReplacementJellyfinPath(
                jellyfinMovie.LibraryPathId,
                path),
            JellyfinEpisode jellyfinEpisode => await _jellyfinPathReplacementService.GetReplacementJellyfinPath(
                jellyfinEpisode.LibraryPathId,
                path),
            EmbyMovie embyMovie => await _embyPathReplacementService.GetReplacementEmbyPath(
                embyMovie.LibraryPathId,
                path),
            EmbyEpisode embyEpisode => await _embyPathReplacementService.GetReplacementEmbyPath(
                embyEpisode.LibraryPathId,
                path),
            _ => path
        });
Exemplo n.º 12
0
    public async Task <Either <BaseError, bool> > RefreshStatistics(
        string ffmpegPath,
        string ffprobePath,
        MediaItem mediaItem,
        string mediaItemPath)
    {
        try
        {
            Either <BaseError, FFprobe> maybeProbe = await GetProbeOutput(ffprobePath, mediaItemPath);

            return(await maybeProbe.Match(
                       async ffprobe =>
            {
                MediaVersion version = ProjectToMediaVersion(mediaItemPath, ffprobe);
                if (version.Duration.TotalSeconds < 1)
                {
                    await AnalyzeDuration(ffmpegPath, mediaItemPath, version);
                }

                bool result = await ApplyVersionUpdate(mediaItem, version, mediaItemPath);
                return Right <BaseError, bool>(result);
            },
                       error => Task.FromResult(Left <BaseError, bool>(error))));
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "Failed to refresh statistics for media item {Id}", mediaItem.Id);
            _client.Notify(ex);
            return(BaseError.New(ex.Message));
        }
    }
Exemplo n.º 13
0
        private async Task <Either <BaseError, PlexEpisode> > UpdateStatistics(
            PlexEpisode existing,
            PlexEpisode incoming,
            PlexConnection connection,
            PlexServerAuthToken token)
        {
            MediaVersion existingVersion = existing.MediaVersions.Head();
            MediaVersion incomingVersion = incoming.MediaVersions.Head();

            if (incomingVersion.DateUpdated > existingVersion.DateUpdated ||
                string.IsNullOrWhiteSpace(existingVersion.SampleAspectRatio))
            {
                Either <BaseError, MediaVersion> maybeStatistics =
                    await _plexServerApiClient.GetStatistics(incoming.Key.Split("/").Last(), connection, token);

                await maybeStatistics.Match(
                    async mediaVersion =>
                {
                    existingVersion.SampleAspectRatio = mediaVersion.SampleAspectRatio ?? "1:1";
                    existingVersion.VideoScanKind     = mediaVersion.VideoScanKind;
                    existingVersion.DateUpdated       = incomingVersion.DateUpdated;

                    await _metadataRepository.UpdatePlexStatistics(existingVersion);
                },
                    _ => Task.CompletedTask);
            }

            return(Right <BaseError, PlexEpisode>(existing));
        }
Exemplo n.º 14
0
            public void Should_NotPadToDesiredResolution_When_NotNormalizingResolution()
            {
                FFmpegProfile ffmpegProfile = TestProfile() with
                {
                    NormalizeResolution = false,
                    Resolution          = new Resolution {
                        Width = 1920, Height = 1080
                    }
                };

                // not anamorphic
                var version = new MediaVersion {
                    Width = 1918, Height = 1080, SampleAspectRatio = "1:1"
                };

                FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                    StreamingMode.TransportStream,
                    ffmpegProfile,
                    version,
                    DateTimeOffset.Now,
                    DateTimeOffset.Now);

                actual.ScaledSize.IsNone.Should().BeTrue();
                actual.PadToDesiredResolution.Should().BeFalse();
            }
Exemplo n.º 15
0
        /// <summary>
        /// Adds or updates the given model in the database
        /// depending on its state.
        /// </summary>
        /// <param name="content">The content to save</param>
        public async Task Save(Models.Media model)
        {
            var media = await _db.Media
                        .Include(m => m.Versions)
                        .FirstOrDefaultAsync(m => m.Id == model.Id)
                        .ConfigureAwait(false);

            if (media == null)
            {
                media = new Media()
                {
                    Id      = model.Id,
                    Created = DateTime.Now
                };
                await _db.Media.AddAsync(media).ConfigureAwait(false);
            }

            media.Filename     = model.Filename;
            media.FolderId     = model.FolderId;
            media.Type         = model.Type;
            media.Size         = model.Size;
            media.Width        = model.Width;
            media.Height       = model.Height;
            media.ContentType  = model.ContentType;
            media.LastModified = DateTime.Now;

            // Delete removed versions
            var current = model.Versions.Select(v => v.Id).ToArray();
            var removed = media.Versions.Where(v => !current.Contains(v.Id)).ToArray();

            if (removed.Length > 0)
            {
                _db.MediaVersions.RemoveRange(removed);
            }

            // Add new versions
            foreach (var version in model.Versions)
            {
                if (media.Versions.All(v => v.Id != version.Id))
                {
                    var mediaVersion = new MediaVersion
                    {
                        Id            = version.Id,
                        MediaId       = media.Id,
                        Size          = version.Size,
                        Width         = version.Width,
                        Height        = version.Height,
                        FileExtension = version.FileExtension
                    };
                    _db.MediaVersions.Add(mediaVersion);
                    media.Versions.Add(mediaVersion);
                }
            }

            // Save all changes
            await _db.SaveChangesAsync().ConfigureAwait(false);
        }
Exemplo n.º 16
0
    private async Task <bool> ApplyVersionUpdate(MediaItem mediaItem, MediaVersion version, string filePath)
    {
        MediaVersion mediaItemVersion = mediaItem.GetHeadVersion();

        bool durationChange = mediaItemVersion.Duration != version.Duration;

        version.DateUpdated = _localFileSystem.GetLastWriteTime(filePath);

        return(await _metadataRepository.UpdateLocalStatistics(mediaItem, version) && durationChange);
    }
Exemplo n.º 17
0
        // **************************************
        // GetContentList
        // **************************************
        public static IList<RemoteContent> GetContentList(MediaVersion version, string filter = null)
        {
            var mediaFolder = GetContentPrefix(version);
            var s3objects = GetBucketList(mediaFolder, RemoteMediaConfiguration.BucketName, filter);

            return s3objects.Select(x => new RemoteContent() {
                Key = x.Key,
                LastUpdatedOn = DateTime.Parse(x.LastModified),
                Size = x.Size
            }).ToList();
        }
Exemplo n.º 18
0
 public Task <bool> UpdatePlexStatistics(MediaVersion mediaVersion) =>
 _dbConnection.ExecuteAsync(
     @"UPDATE MediaVersion SET
           SampleAspectRatio = @SampleAspectRatio,
           VideoScanKind = @VideoScanKind,
           DateUpdated = @DateUpdated
           WHERE Id = @MediaVersionId",
     new
 {
     mediaVersion.SampleAspectRatio,
     mediaVersion.VideoScanKind,
     mediaVersion.DateUpdated,
     MediaVersionId = mediaVersion.Id
 }).Map(result => result > 0);
Exemplo n.º 19
0
    private async Task AddLanguages(ISearchRepository searchRepository, Document doc, List <MediaVersion> mediaVersions)
    {
        Option <MediaVersion> maybeVersion = mediaVersions.HeadOrNone();

        if (maybeVersion.IsSome)
        {
            MediaVersion version    = maybeVersion.ValueUnsafe();
            var          mediaCodes = version.Streams
                                      .Filter(ms => ms.MediaStreamKind == MediaStreamKind.Audio)
                                      .Map(ms => ms.Language).Distinct()
                                      .ToList();

            await AddLanguages(searchRepository, doc, mediaCodes);
        }
    }
    public void Test()
    {
        var provider = new LocalStatisticsProvider(
            new Mock <IMetadataRepository>().Object,
            new Mock <ILocalFileSystem>().Object,
            new Mock <IClient>().Object,
            new Mock <ILogger <LocalStatisticsProvider> >().Object);

        var input = new LocalStatisticsProvider.FFprobe(
            new LocalStatisticsProvider.FFprobeFormat("123.45", null),
            new List <LocalStatisticsProvider.FFprobeStream>(),
            new List <LocalStatisticsProvider.FFprobeChapter>());

        MediaVersion result = provider.ProjectToMediaVersion("test", input);

        result.Duration.Should().Be(TimeSpan.FromSeconds(123.45));
    }
Exemplo n.º 21
0
        private async Task <string> GetPlayoutItemPath(PlayoutItem playoutItem)
        {
            MediaVersion version = playoutItem.MediaItem switch
            {
                Movie m => m.MediaVersions.Head(),
                Episode e => e.MediaVersions.Head(),
                         _ => throw new ArgumentOutOfRangeException(nameof(playoutItem))
            };

            MediaFile file = version.MediaFiles.Head();
            string    path = file.Path;

            return(playoutItem.MediaItem switch
            {
                PlexMovie plexMovie => await GetReplacementPlexPath(plexMovie.LibraryPathId, path),
                PlexEpisode plexEpisode => await GetReplacementPlexPath(plexEpisode.LibraryPathId, path),
                _ => path
            });
Exemplo n.º 22
0
            public void Should_SetAudioBufferSize_When_NormalizingWrongCodec_ForTransportStream()
            {
                FFmpegProfile ffmpegProfile = TestProfile() with
                {
                    NormalizeAudioCodec = true,
                    AudioBufferSize     = 2424
                };

                var version = new MediaVersion {
                    AudioCodec = "ac3"
                };

                FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                    StreamingMode.TransportStream,
                    ffmpegProfile,
                    version,
                    DateTimeOffset.Now,
                    DateTimeOffset.Now);

                actual.AudioBufferSize.IfNone(0).Should().Be(2424);
            }
Exemplo n.º 23
0
            public void Should_SetCopyAudioCodec_When_NormalizingWrongCodec_ForHttpLiveStreaming()
            {
                FFmpegProfile ffmpegProfile = TestProfile() with
                {
                    NormalizeAudioCodec = true,
                    AudioCodec          = "aac"
                };

                var version = new MediaVersion {
                    AudioCodec = "ac3"
                };

                FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                    StreamingMode.HttpLiveStreaming,
                    ffmpegProfile,
                    version,
                    DateTimeOffset.Now,
                    DateTimeOffset.Now);

                actual.AudioCodec.Should().Be("copy");
            }
Exemplo n.º 24
0
            public void ShouldNot_SetAudioSampleRate_When_CorrectCodec_ForTransportStream()
            {
                FFmpegProfile ffmpegProfile = TestProfile() with
                {
                    NormalizeAudioCodec = true,
                    NormalizeAudio      = true,
                    AudioCodec          = "ac3",
                    AudioSampleRate     = 48
                };

                var version = new MediaVersion {
                    AudioCodec = "ac3"
                };

                FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                    StreamingMode.TransportStream,
                    ffmpegProfile,
                    version,
                    DateTimeOffset.Now,
                    DateTimeOffset.Now);

                actual.AudioSampleRate.IsNone.Should().BeTrue();
            }
Exemplo n.º 25
0
        private MediaVersion ProjectToMediaVersion(FFprobe probeOutput) =>
        Optional(probeOutput)
        .Filter(json => json?.format != null && json.streams != null)
        .ToValidation <BaseError>("Unable to parse ffprobe output")
        .ToEither <FFprobe>()
        .Match(
            json =>
        {
            var duration = TimeSpan.FromSeconds(double.Parse(json.format.duration));

            var version = new MediaVersion {
                Name = "Main", Duration = duration
            };

            FFprobeStream audioStream = json.streams.FirstOrDefault(s => s.codec_type == "audio");
            if (audioStream != null)
            {
                version.AudioCodec = audioStream.codec_name;
            }

            FFprobeStream videoStream = json.streams.FirstOrDefault(s => s.codec_type == "video");
            if (videoStream != null)
            {
                version.SampleAspectRatio  = videoStream.sample_aspect_ratio;
                version.DisplayAspectRatio = videoStream.display_aspect_ratio;
                version.Width         = videoStream.width;
                version.Height        = videoStream.height;
                version.VideoCodec    = videoStream.codec_name;
                version.VideoProfile  = (videoStream.profile ?? string.Empty).ToLowerInvariant();
                version.VideoScanKind = ScanKindFromFieldOrder(videoStream.field_order);
            }

            return(version);
        },
            _ => new MediaVersion {
            Name = "Main"
        });
Exemplo n.º 26
0
            public void ShouldNot_SetScaledSize_When_ContentIsCorrectSize_ForTransportStream()
            {
                FFmpegProfile ffmpegProfile = TestProfile() with
                {
                    NormalizeResolution = true,
                    Resolution          = new Resolution {
                        Width = 1920, Height = 1080
                    }
                };

                // not anamorphic
                var version = new MediaVersion {
                    Width = 1920, Height = 1080, SampleAspectRatio = "1:1"
                };

                FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
                    StreamingMode.TransportStream,
                    ffmpegProfile,
                    version,
                    DateTimeOffset.Now,
                    DateTimeOffset.Now);

                actual.ScaledSize.IsNone.Should().BeTrue();
            }
Exemplo n.º 27
0
        private async Task <bool> ApplyVersionUpdate(MediaItem mediaItem, MediaVersion version, string filePath)
        {
            MediaVersion mediaItemVersion = mediaItem switch
            {
                Movie m => m.MediaVersions.Head(),
                Episode e => e.MediaVersions.Head(),
                         _ => throw new ArgumentOutOfRangeException(nameof(mediaItem))
            };

            bool durationChange = mediaItemVersion.Duration != version.Duration;

            mediaItemVersion.DateUpdated        = _localFileSystem.GetLastWriteTime(filePath);
            mediaItemVersion.Duration           = version.Duration;
            mediaItemVersion.AudioCodec         = version.AudioCodec;
            mediaItemVersion.SampleAspectRatio  = version.SampleAspectRatio;
            mediaItemVersion.DisplayAspectRatio = version.DisplayAspectRatio;
            mediaItemVersion.Width         = version.Width;
            mediaItemVersion.Height        = version.Height;
            mediaItemVersion.VideoCodec    = version.VideoCodec;
            mediaItemVersion.VideoProfile  = version.VideoProfile;
            mediaItemVersion.VideoScanKind = version.VideoScanKind;

            return(await _metadataRepository.UpdateLocalStatistics(mediaItemVersion) && durationChange);
        }
Exemplo n.º 28
0
        public virtual ActionResult StreamUrl(int id, MediaVersion version = MediaVersion.Preview)
        {
            try {
                var contentType = "application/mp3";
                Response.ContentType = contentType;
                var mediaUrl = GetUrl(id, version);

                if (mediaUrl != null){
                    return Redirect(mediaUrl);
                } else {
                var msg = "You do not have access to this file";
                    this.FeedbackError(msg);
                    var ex = new AccessViolationException(msg);
                    Log.Error(ex);
                    return RedirectToAction(MVC.Error.Problem());
                }
            }
            catch (Exception ex) {
                Log.Error(ex);

                this.FeedbackError("There was an error loading this page. Please try again in a bit.");
                return RedirectToAction(MVC.Search.Index());
            }
        }
Exemplo n.º 29
0
 // **************************************
 // Stream
 // **************************************
 //[OutputCache(Duration = 60, VaryByParam = "id;version")]
 private string GetUrl(int id, MediaVersion version = MediaVersion.Preview)
 {
     var content = SearchService.GetContent(id, Account.User());
     var contentMedia = content.ContentMedia.SingleOrDefault(x => x.MediaVersion == (int)version);
     if (content != null) {
         return MediaService.GetContentMediaPath(contentMedia);
     } else {
         return null;
     }
 }
Exemplo n.º 30
0
 public static ContentMedia Media(this Content content, MediaVersion version)
 {
     return content.ContentMedia != null ?
         content.ContentMedia.SingleOrDefault(x => x.MediaVersion == (int)version)
         : null;
 }
Exemplo n.º 31
0
        //// **************************************
        //// Download
        //// **************************************
        //public virtual ActionResult DownloadUrl(int id) {
        //    try {
        //        var contentType = "application/unknown";
        //        Response.ContentType = contentType;
        //        var mediaUrl = GetUrl(id, MediaVersion.Full);
        //        if (mediaUrl != null) {
        //            return Redirect(mediaUrl);
        //        } else {
        //            var msg = "You do not have access to this file";
        //            this.FeedbackError(msg);
        //            return RedirectToAction(MVC.Error.Index(new AccessViolationException(msg), msg, "Media", "Stream"));
        //        }
        //    }
        //    catch {
        //        this.FeedbackError("There was an error loading this page. Please try again in a bit.");
        //        return RedirectToAction(MVC.Search.Index());
        //    }
        //}
        //// **************************************
        //// Download
        //// **************************************
        ////[OutputCache(Duration = 60, VaryByParam = "id;version")]
        //public virtual ActionResult Get(int id, MediaVersion version = MediaVersion.Preview) {
        //    var user = Account.User();
        //    var content = SearchService.GetContent(id, user);
        //    if (content != null) {
        //        var downloadName = String.Concat(content.UserDownloadableName, SystemConfig.MediaDefaultExtension);
        //        var contentType = "application/unknown";
        //        Response.ContentType = contentType;
        //        if (SystemConfig.UseRemoteMedia) {
        //            var url = GetUrl(id, version);
        //            return base.File(url, contentType, downloadName);
        //        } else {
        //            var media = _mediaService.GetContentMedia(id, (MediaVersion)version, user);
        //            return base.File(media, contentType, downloadName);
        //        }
        //    } else {
        //        var msg = "You do not have access to this file";
        //        this.FeedbackError(msg);
        //        return RedirectToAction(MVC.Error.Index(new AccessViolationException(msg), msg, "Media", "Download" ));
        //    }
        //}
        // **************************************
        // Stream
        // **************************************
        //[OutputCache(Duration = 60, VaryByParam = "id;version")]
        public virtual ActionResult Stream(int id, MediaVersion version = MediaVersion.Preview)
        {
            try {

                var content = SearchService.GetContent(id, Account.User());
                var contentMedia = content.ContentMedia.SingleOrDefault(x => x.MediaVersion == (int)version);

                if (content != null) {

                    if (SystemConfig.UseRemoteMedia && content.IsMediaOnRemoteServer) {

                        return RedirectToAction(Actions.StreamUrl(id, version));

                    } else {

                        var mediaPath = MediaService.GetContentMediaPath(contentMedia);
                        var contentType = "application/mp3";
                        Response.ContentType = contentType;

                        return new FileStreamResult(new FileStream(mediaPath, System.IO.FileMode.Open), contentType);
                    }
                } else {
                    var msg = "You do not have access to this file";
                    this.FeedbackError(msg);
                    var ex = new AccessViolationException(msg);
                    Log.Error(ex);
                    return RedirectToAction(MVC.Error.Problem());
                }

            }
            catch (Exception ex) {
                Log.Error(ex);

                this.FeedbackError("There was an error loading this page. Please try again in a bit.");
                return RedirectToAction(MVC.Search.Index());
            }
        }
Exemplo n.º 32
0
 // **************************************
 // GetContentPrefix
 // **************************************
 public static string GetContentPrefix(MediaVersion version)
 {
     return String.Format(SystemConfig.MediaFolderUrlFormat, version.ToString());
 }
    protected override async Task <Either <BaseError, PlayoutItemProcessModel> > GetProcess(
        TvContext dbContext,
        GetPlayoutItemProcessByChannelNumber request,
        Channel channel,
        string ffmpegPath,
        string ffprobePath,
        CancellationToken cancellationToken)
    {
        DateTimeOffset now = request.Now;

        Either <BaseError, PlayoutItemWithPath> maybePlayoutItem = await dbContext.PlayoutItems
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as Episode).EpisodeMetadata)
                                                                   .ThenInclude(em => em.Subtitles)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as Episode).MediaVersions)
                                                                   .ThenInclude(mv => mv.MediaFiles)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as Episode).MediaVersions)
                                                                   .ThenInclude(mv => mv.Streams)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as Movie).MovieMetadata)
                                                                   .ThenInclude(mm => mm.Subtitles)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as Movie).MediaVersions)
                                                                   .ThenInclude(mv => mv.MediaFiles)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as Movie).MediaVersions)
                                                                   .ThenInclude(mv => mv.Streams)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as MusicVideo).MusicVideoMetadata)
                                                                   .ThenInclude(mvm => mvm.Subtitles)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as MusicVideo).MediaVersions)
                                                                   .ThenInclude(mv => mv.MediaFiles)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as MusicVideo).MediaVersions)
                                                                   .ThenInclude(mv => mv.Streams)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as OtherVideo).OtherVideoMetadata)
                                                                   .ThenInclude(ovm => ovm.Subtitles)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as OtherVideo).MediaVersions)
                                                                   .ThenInclude(ov => ov.MediaFiles)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as OtherVideo).MediaVersions)
                                                                   .ThenInclude(ov => ov.Streams)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as Song).MediaVersions)
                                                                   .ThenInclude(mv => mv.MediaFiles)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as Song).MediaVersions)
                                                                   .ThenInclude(mv => mv.Streams)
                                                                   .Include(i => i.MediaItem)
                                                                   .ThenInclude(mi => (mi as Song).SongMetadata)
                                                                   .ThenInclude(sm => sm.Artwork)
                                                                   .Include(i => i.Watermark)
                                                                   .ForChannelAndTime(channel.Id, now)
                                                                   .Map(o => o.ToEither <BaseError>(new UnableToLocatePlayoutItem()))
                                                                   .BindT(ValidatePlayoutItemPath);

        if (maybePlayoutItem.LeftAsEnumerable().Any(e => e is UnableToLocatePlayoutItem))
        {
            maybePlayoutItem = await CheckForFallbackFiller(dbContext, channel, now);
        }

        foreach (PlayoutItemWithPath playoutItemWithPath in maybePlayoutItem.RightToSeq())
        {
            MediaVersion version = playoutItemWithPath.PlayoutItem.MediaItem.GetHeadVersion();

            string       videoPath    = playoutItemWithPath.Path;
            MediaVersion videoVersion = version;

            string       audioPath    = playoutItemWithPath.Path;
            MediaVersion audioVersion = version;

            Option <ChannelWatermark> maybeGlobalWatermark = await dbContext.ConfigElements
                                                             .GetValue <int>(ConfigElementKey.FFmpegGlobalWatermarkId)
                                                             .BindT(
                watermarkId => dbContext.ChannelWatermarks
                .SelectOneAsync(w => w.Id, w => w.Id == watermarkId));

            if (playoutItemWithPath.PlayoutItem.MediaItem is Song song)
            {
                (videoPath, videoVersion) = await _songVideoGenerator.GenerateSongVideo(
                    song,
                    channel,
                    Optional(playoutItemWithPath.PlayoutItem.Watermark),
                    maybeGlobalWatermark,
                    ffmpegPath,
                    ffprobePath,
                    cancellationToken);
            }

            bool saveReports = await dbContext.ConfigElements
                               .GetValue <bool>(ConfigElementKey.FFmpegSaveReports)
                               .Map(result => result.IfNone(false));

            List <Subtitle> subtitles = GetSubtitles(playoutItemWithPath);

            Command process = await _ffmpegProcessService.ForPlayoutItem(
                ffmpegPath,
                ffprobePath,
                saveReports,
                channel,
                videoVersion,
                audioVersion,
                videoPath,
                audioPath,
                subtitles,
                playoutItemWithPath.PlayoutItem.PreferredAudioLanguageCode ?? channel.PreferredAudioLanguageCode,
                playoutItemWithPath.PlayoutItem.PreferredSubtitleLanguageCode ?? channel.PreferredSubtitleLanguageCode,
                playoutItemWithPath.PlayoutItem.SubtitleMode ?? channel.SubtitleMode,
                playoutItemWithPath.PlayoutItem.StartOffset,
                playoutItemWithPath.PlayoutItem.FinishOffset,
                request.StartAtZero?playoutItemWithPath.PlayoutItem.StartOffset : now,
                Optional(playoutItemWithPath.PlayoutItem.Watermark),
                maybeGlobalWatermark,
                channel.FFmpegProfile.VaapiDriver,
                channel.FFmpegProfile.VaapiDevice,
                request.HlsRealtime,
                playoutItemWithPath.PlayoutItem.FillerKind,
                playoutItemWithPath.PlayoutItem.InPoint,
                playoutItemWithPath.PlayoutItem.OutPoint,
                request.PtsOffset,
                request.TargetFramerate);

            var result = new PlayoutItemProcessModel(
                process,
                playoutItemWithPath.PlayoutItem.FinishOffset -
                (request.StartAtZero ? playoutItemWithPath.PlayoutItem.StartOffset : now),
                playoutItemWithPath.PlayoutItem.FinishOffset);

            return(Right <BaseError, PlayoutItemProcessModel>(result));
        }

        foreach (BaseError error in maybePlayoutItem.LeftToSeq())
        {
            Option <TimeSpan> maybeDuration = await dbContext.PlayoutItems
                                              .Filter(pi => pi.Playout.ChannelId == channel.Id)
                                              .Filter(pi => pi.Start > now.UtcDateTime)
                                              .OrderBy(pi => pi.Start)
                                              .FirstOrDefaultAsync(cancellationToken)
                                              .Map(Optional)
                                              .MapT(pi => pi.StartOffset - now);

            DateTimeOffset finish = maybeDuration.Match(d => now.Add(d), () => now);

            switch (error)
            {
            case UnableToLocatePlayoutItem:
                Command offlineProcess = await _ffmpegProcessService.ForError(
                    ffmpegPath,
                    channel,
                    maybeDuration,
                    "Channel is Offline",
                    request.HlsRealtime,
                    request.PtsOffset);

                return(new PlayoutItemProcessModel(offlineProcess, maybeDuration, finish));

            case PlayoutItemDoesNotExistOnDisk:
                Command doesNotExistProcess = await _ffmpegProcessService.ForError(
                    ffmpegPath,
                    channel,
                    maybeDuration,
                    error.Value,
                    request.HlsRealtime,
                    request.PtsOffset);

                return(new PlayoutItemProcessModel(doesNotExistProcess, maybeDuration, finish));

            default:
                Command errorProcess = await _ffmpegProcessService.ForError(
                    ffmpegPath,
                    channel,
                    maybeDuration,
                    "Channel is Offline",
                    request.HlsRealtime,
                    request.PtsOffset);

                return(new PlayoutItemProcessModel(errorProcess, maybeDuration, finish));
            }
        }

        return(BaseError.New($"Unexpected error locating playout item for channel {channel.Number}"));
    }
    private async Task <Either <BaseError, PlayoutItemWithPath> > CheckForFallbackFiller(
        TvContext dbContext,
        Channel channel,
        DateTimeOffset now)
    {
        // check for channel fallback
        Option <FillerPreset> maybeFallback = await dbContext.FillerPresets
                                              .SelectOneAsync(w => w.Id, w => w.Id == channel.FallbackFillerId);

        // then check for global fallback
        if (maybeFallback.IsNone)
        {
            maybeFallback = await dbContext.ConfigElements
                            .GetValue <int>(ConfigElementKey.FFmpegGlobalFallbackFillerId)
                            .BindT(fillerId => dbContext.FillerPresets.SelectOneAsync(w => w.Id, w => w.Id == fillerId));
        }

        foreach (FillerPreset fallbackPreset in maybeFallback)
        {
            // turn this into a playout item

            var collectionKey      = CollectionKey.ForFillerPreset(fallbackPreset);
            List <MediaItem> items = await MediaItemsForCollection.Collect(
                _mediaCollectionRepository,
                _televisionRepository,
                _artistRepository,
                collectionKey);

            // TODO: shuffle? does it really matter since we loop anyway
            MediaItem item = items[new Random().Next(items.Count)];

            Option <TimeSpan> maybeDuration = await dbContext.PlayoutItems
                                              .Filter(pi => pi.Playout.ChannelId == channel.Id)
                                              .Filter(pi => pi.Start > now.UtcDateTime)
                                              .OrderBy(pi => pi.Start)
                                              .FirstOrDefaultAsync()
                                              .Map(Optional)
                                              .MapT(pi => pi.StartOffset - now);

            MediaVersion version = item.GetHeadVersion();

            version.MediaFiles = await dbContext.MediaFiles
                                 .AsNoTracking()
                                 .Filter(mf => mf.MediaVersionId == version.Id)
                                 .ToListAsync();

            version.Streams = await dbContext.MediaStreams
                              .AsNoTracking()
                              .Filter(ms => ms.MediaVersionId == version.Id)
                              .ToListAsync();

            DateTimeOffset finish = maybeDuration.Match(
                // next playout item exists
                // loop until it starts
                now.Add,
                // no next playout item exists
                // loop for 5 minutes if less than 30s, otherwise play full item
                () => version.Duration < TimeSpan.FromSeconds(30)
                    ? now.AddMinutes(5)
                    : now.Add(version.Duration));

            var playoutItem = new PlayoutItem
            {
                MediaItem   = item,
                MediaItemId = item.Id,
                Start       = now.UtcDateTime,
                Finish      = finish.UtcDateTime,
                FillerKind  = FillerKind.Fallback,
                InPoint     = TimeSpan.Zero,
                OutPoint    = version.Duration
            };

            return(await ValidatePlayoutItemPath(playoutItem));
        }

        return(new UnableToLocatePlayoutItem());
    }
Exemplo n.º 35
0
        public static IList<UploadFile> GetUploadFiles(this IList<string> tempFiles, MediaVersion mediaVersion)
        {
            var uploadFiles = new List<UploadFile>();
            tempFiles.ForEach(f =>
                uploadFiles.Add(new UploadFile() { FileMediaVersion = mediaVersion, FilePath = f, FileName = Path.GetFileName(f) })
            );

            return uploadFiles;
        }
Exemplo n.º 36
0
        public static void Upload(MediaVersion version)
        {
            using (_amazon = new AmazonCloudService()) {

                using (var session = new SongSearchDataSession()) {

                    var contents = session.All<Content>().ToList();
                    var remoteContents = _amazon.GetContentList(version);
                    var remoteFolder = _amazon.GetContentPrefix(version);

                    foreach (var content in contents) {
                        var dbContent = session.Single<Content>(c => c.ContentId == content.ContentId);
                        var key = _amazon.GetContentKey(content.Media(version));
                        var filePath = Path.Combine(version == MediaVersion.Full ?
                            SystemConfig.MediaPathFull :
                            SystemConfig.MediaPathPreview,
                            String.Concat(content.ContentId,SystemConfig.MediaDefaultExtension)
                            );

                        var file = new FileInfo(filePath);
                        if (file.Exists) {
                            var remoteFile = remoteContents.SingleOrDefault(x => x.Key == key && x.Size == file.Length);

                            if (remoteFile == null) {

                                try {
                                    Console.WriteLine("Uploading " + file.Name + " to " + remoteFolder);
                                    _amazon.PutContentMedia(file.FullName, content.Media(version));
                                    dbContent.IsMediaOnRemoteServer = true;
                                }
                                catch (Exception ex){
                                    Console.WriteLine("FAILED: " + file.Name + "-------------------");
                                    Console.WriteLine("ERROR: " + ex.Message);
                                    dbContent.IsMediaOnRemoteServer = false;
                                }
                            } else {
                                dbContent.IsMediaOnRemoteServer = true;
                            }
                        } else {
                            dbContent.IsMediaOnRemoteServer = false;
                        }
                        session.CommitChanges();
                    }

                    Console.WriteLine("Done uploading");

                }
            }
        }
Exemplo n.º 37
0
        // **************************************
        // MoveToMediaVersionFolder
        // **************************************
        private IList<UploadFile> MoveToMediaVersionFolder(List<string> files, MediaVersion mediaVersion)
        {
            var newFiles = new List<string>();
            var user = Account.User();

            foreach (var file in files) {
                var filePath = user.UploadFile(fileName: file);

                if (File.Exists(filePath)) {

                    var newFilePath = user.UploadFile(file, mediaVersion.ToString());
                    if (File.Exists(newFilePath)) { File.Delete(newFilePath); }

                    File.Move(filePath, newFilePath);
                    newFiles.Add(newFilePath);
                }
            }
            return newFiles.GetUploadFiles(mediaVersion);
        }
Exemplo n.º 38
0
        protected override async Task <Either <BaseError, Process> > GetProcess(
            GetPlayoutItemProcessByChannelNumber _,
            Channel channel,
            string ffmpegPath)
        {
            DateTimeOffset now = DateTimeOffset.Now;
            Either <BaseError, PlayoutItemWithPath> maybePlayoutItem = await _playoutRepository
                                                                       .GetPlayoutItem(channel.Id, now)
                                                                       .Map(o => o.ToEither <BaseError>(new UnableToLocatePlayoutItem()))
                                                                       .BindT(ValidatePlayoutItemPath);

            return(await maybePlayoutItem.Match(
                       async playoutItemWithPath =>
            {
                MediaVersion version = playoutItemWithPath.PlayoutItem.MediaItem switch
                {
                    Movie m => m.MediaVersions.Head(),
                    Episode e => e.MediaVersions.Head(),
                    _ => throw new ArgumentOutOfRangeException(nameof(playoutItemWithPath))
                };

                bool saveReports = await _configElementRepository.GetValue <bool>(ConfigElementKey.FFmpegSaveReports)
                                   .Map(result => result.IfNone(false));

                return Right <BaseError, Process>(
                    _ffmpegProcessService.ForPlayoutItem(
                        ffmpegPath,
                        saveReports,
                        channel,
                        version,
                        playoutItemWithPath.Path,
                        playoutItemWithPath.PlayoutItem.StartOffset,
                        now));
            },
                       async error =>
            {
                var offlineTranscodeMessage =
                    $"offline image is unavailable because transcoding is disabled in ffmpeg profile '{channel.FFmpegProfile.Name}'";

                Option <TimeSpan> maybeDuration = await Optional(channel.FFmpegProfile.Transcode)
                                                  .Filter(transcode => transcode)
                                                  .Match(
                    _ => _playoutRepository.GetNextItemStart(channel.Id, now)
                    .MapT(nextStart => nextStart - now),
                    () => Option <TimeSpan> .None.AsTask());

                switch (error)
                {
                case UnableToLocatePlayoutItem:
                    if (channel.FFmpegProfile.Transcode)
                    {
                        return _ffmpegProcessService.ForError(
                            ffmpegPath,
                            channel,
                            maybeDuration,
                            "Channel is Offline");
                    }
                    else
                    {
                        var message =
                            $"Unable to locate playout item for channel {channel.Number}; {offlineTranscodeMessage}";

                        return BaseError.New(message);
                    }

                case PlayoutItemDoesNotExistOnDisk:
                    if (channel.FFmpegProfile.Transcode)
                    {
                        return _ffmpegProcessService.ForError(ffmpegPath, channel, maybeDuration, error.Value);
                    }
                    else
                    {
                        var message =
                            $"Playout item does not exist on disk for channel {channel.Number}; {offlineTranscodeMessage}";

                        return BaseError.New(message);
                    }

                default:
                    if (channel.FFmpegProfile.Transcode)
                    {
                        return _ffmpegProcessService.ForError(
                            ffmpegPath,
                            channel,
                            maybeDuration,
                            "Channel is Offline");
                    }
                    else
                    {
                        var message =
                            $"Unexpected error locating playout item for channel {channel.Number}; {offlineTranscodeMessage}";

                        return BaseError.New(message);
                    }
                }
            }));
        }
Exemplo n.º 39
0
        // **************************************
        // UploadToRemote
        // **************************************
        public static void UploadToRemote(bool checkSize = false, bool onlyNewContent = false, MediaVersion[] mediaVersions = null)
        {
            Log.Debug(String.Format("Starting Amazon upload at {0}", DateTime.Now));

            using (var ctx = new SongSearchContext()) {

                var query = ctx.Contents.AsQueryable();

                if (onlyNewContent) {
                    query = query.Where(c => c.ContentMedia.Any(m => m.IsRemote == false));
                }

                var contents = query.ToList();
                if (contents.Count > 0) {

                    Log.Debug("Getting remote file list");

                    var remoteList = GetRemoteFileList(mediaVersions ?? new MediaVersion[] { MediaVersion.Preview, MediaVersion.Full });

                    //var remoteFolder = AmazonCloudService.GetContentPrefix(version);

                    Log.Debug("Comparing " + contents.Count + " content items");

                    foreach (var content in contents) {

                        Log.Debug("Checking ContentId " + content.ContentId);

                        var dbContent = ctx.Contents.SingleOrDefault(c => c.ContentId == content.ContentId);
                        var contentMedia = dbContent.ContentMedia.ToList();

                        if (mediaVersions != null) {
                            contentMedia = contentMedia.Where(c => mediaVersions.Contains((MediaVersion)c.MediaVersion)).ToList();
                        }

                        foreach (var media in contentMedia) {

                            var key = AmazonCloudService.GetContentKey(media);
                            var remoteMedia = remoteList[(MediaVersion)media.MediaVersion];

                            var filePath = Path.Combine((MediaVersion)media.MediaVersion == MediaVersion.Full ?
                                SystemConfig.MediaPathFull :
                                SystemConfig.MediaPathPreview,
                                String.Concat(content.ContentId, SystemConfig.MediaDefaultExtension)
                                );

                            var file = new FileInfo(filePath);

                            if (file.Exists) {
                                var remoteFile = checkSize ? remoteMedia.SingleOrDefault(x => x.Key == key && x.Size == file.Length)
                                    : remoteMedia.SingleOrDefault(x => x.Key == key);

                                if (remoteFile == null) {

                                    try {
                                        AmazonCloudService.PutContentMedia(file.FullName, media);

                                        Log.Debug(String.Format("Uploaded local file {0}", file.FullName));

                                        media.IsRemote = true;
                                    }
                                    catch (Exception ex) {
                                        Log.Error(ex);

                                        media.IsRemote = false;
                                        continue;
                                    }
                                } else {
                                    Log.Debug(String.Format("File for {0} matches", content.ContentId));
                                    media.IsRemote = true;
                                }
                            } else {
                                // file is not local, let's see if it's remote
                                var remoteFile = remoteMedia.SingleOrDefault(x => x.Key == key);
                                if (remoteFile != null) {
                                    //if (checkSize) {
                                    //RepushMedia(content, media, filePath, file);
                                    media.IsRemote = true;
                                    //}
                                } else {
                                    media.IsRemote = false;
                                }
                            }
                        }
                        ctx.SaveChanges();
                    }

                    //				DataSession.CommitChanges();
                    Log.Debug(String.Format("Completed Amazon upload at {0}", DateTime.Now));
                }
            }
        }
Exemplo n.º 40
0
        public async Task <string> EnsureVersionAsync(Media media, int width, int?height = null)
        {
            // Get the media type
            var type = App.MediaTypes.GetItem(media.Filename);

            // If this type doesn't allow processing, return the original url
            if (!type.AllowProcessing)
            {
                return(GetPublicUrl(media));
            }

            // If the requested size is equal to the original size, return true
            if (media.Width == width && (!height.HasValue || media.Height == height.Value))
            {
                return(GetPublicUrl(media));
            }

            var query = media.Versions
                        .Where(v => v.Width == width);

            query = height.HasValue ? query.Where(v => v.Height == height) : query.Where(v => !v.Height.HasValue);

            var version = query.FirstOrDefault();

            if (version != null)
            {
                return(media.Width == width && (!height.HasValue || media.Height == height.Value)
                    ? GetPublicUrl(media)
                    : GetPublicUrl(media, width, height, version.FileExtension));
            }

            // Get the image file
            using (var stream = new MemoryStream())
            {
                using (var session = await _storage.OpenAsync().ConfigureAwait(false))
                {
                    if (!await session.GetAsync(media.Id + "-" + media.Filename, stream).ConfigureAwait(false))
                    {
                        return(null);
                    }

                    // Reset strem position
                    stream.Position = 0;

                    using (var output = new MemoryStream())
                    {
                        if (height.HasValue)
                        {
                            _processor.CropScale(stream, output, width, height.Value);
                        }
                        else
                        {
                            _processor.Scale(stream, output, width);
                        }
                        output.Position = 0;
                        bool upload = false;

                        lock (ScaleMutex)
                        {
                            // We have to make sure we don't scale multiple files
                            // at the same time as it can create index violations.
                            version = query.FirstOrDefault();

                            if (version == null)
                            {
                                var info = new FileInfo(media.Filename);

                                version = new MediaVersion
                                {
                                    Id            = Guid.NewGuid(),
                                    Size          = output.Length,
                                    Width         = width,
                                    Height        = height,
                                    FileExtension = info.Extension
                                };
                                media.Versions.Add(version);

                                _repo.Save(media).Wait();
                                RemoveFromCache(media);

                                upload = true;
                            }
                        }

                        if (upload)
                        {
                            return(await session.PutAsync(GetResourceName(media, width, height), media.ContentType,
                                                          output)
                                   .ConfigureAwait(false));
                        }
                        //When moving this out of its parent method, realized that if the mutex failed, it would just fall back to the null instead of trying to return the issue.
                        //Added this to ensure that queries didn't just give up if they weren't the first to the party.
                        return(GetPublicUrl(media, width, height, version.FileExtension));
                    }
                }
            }
            // If the requested size is equal to the original size, return true
        }
Exemplo n.º 41
0
 private static Dictionary<MediaVersion, IList<RemoteContent>> GetRemoteFileList(MediaVersion[] versions)
 {
     var remoteList = new Dictionary<MediaVersion, IList<RemoteContent>>();
     versions.ForEach(v =>
         remoteList.Add(v, AmazonCloudService.GetContentList(v))
     );
     return remoteList;
 }