mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-04 03:27:21 -05:00 
			
		
		
		
	add chapter image error handling
This commit is contained in:
		
							parent
							
								
									cc7b150b90
								
							
						
					
					
						commit
						d4324b7e89
					
				@ -1791,8 +1791,7 @@ namespace MediaBrowser.Api.Playback
 | 
				
			|||||||
                if (!string.IsNullOrWhiteSpace(state.VideoRequest.VideoCodec))
 | 
					                if (!string.IsNullOrWhiteSpace(state.VideoRequest.VideoCodec))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    state.SupportedVideoCodecs = state.VideoRequest.VideoCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
 | 
					                    state.SupportedVideoCodecs = state.VideoRequest.VideoCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
 | 
				
			||||||
                    state.VideoRequest.VideoCodec = state.SupportedVideoCodecs.FirstOrDefault(i => MediaEncoder.CanEncodeToAudioCodec(i))
 | 
					                    state.VideoRequest.VideoCodec = state.SupportedVideoCodecs.FirstOrDefault();
 | 
				
			||||||
                        ?? state.SupportedVideoCodecs.FirstOrDefault();
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
using MediaBrowser.Controller.Entities;
 | 
					using MediaBrowser.Controller.Entities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MediaBrowser.Server.Implementations.Collections
 | 
					namespace MediaBrowser.Controller.Collections
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public class ManualCollectionsFolder : BasePluginFolder, IHiddenFromDisplay
 | 
					    public class ManualCollectionsFolder : BasePluginFolder, IHiddenFromDisplay
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -113,8 +113,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            var standaloneTypes = new List<string>
 | 
					            var standaloneTypes = new List<string>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                CollectionType.Playlists,
 | 
					                CollectionType.Playlists
 | 
				
			||||||
                CollectionType.BoxSets
 | 
					 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var collectionFolder = folder as ICollectionFolder;
 | 
					            var collectionFolder = folder as ICollectionFolder;
 | 
				
			||||||
 | 
				
			|||||||
@ -98,6 +98,7 @@
 | 
				
			|||||||
    <Compile Include="Collections\CollectionCreationOptions.cs" />
 | 
					    <Compile Include="Collections\CollectionCreationOptions.cs" />
 | 
				
			||||||
    <Compile Include="Collections\CollectionEvents.cs" />
 | 
					    <Compile Include="Collections\CollectionEvents.cs" />
 | 
				
			||||||
    <Compile Include="Collections\ICollectionManager.cs" />
 | 
					    <Compile Include="Collections\ICollectionManager.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Collections\ManualCollectionsFolder.cs" />
 | 
				
			||||||
    <Compile Include="Connect\ConnectSupporterSummary.cs" />
 | 
					    <Compile Include="Connect\ConnectSupporterSummary.cs" />
 | 
				
			||||||
    <Compile Include="Connect\IConnectManager.cs" />
 | 
					    <Compile Include="Connect\IConnectManager.cs" />
 | 
				
			||||||
    <Compile Include="Connect\UserLinkResult.cs" />
 | 
					    <Compile Include="Connect\UserLinkResult.cs" />
 | 
				
			||||||
 | 
				
			|||||||
@ -790,20 +790,25 @@ namespace MediaBrowser.Controller.Providers
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                default:
 | 
					                default:
 | 
				
			||||||
                    if (_validProviderIds.ContainsKey(reader.Name))
 | 
					                {
 | 
				
			||||||
                    {
 | 
					                        string readerName = reader.Name;
 | 
				
			||||||
                        var id = reader.ReadElementContentAsString();
 | 
					                        string providerIdValue;
 | 
				
			||||||
                        if (!string.IsNullOrWhiteSpace(id))
 | 
					                        if (_validProviderIds.TryGetValue(readerName, out providerIdValue))
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            item.SetProviderId(_validProviderIds[reader.Name], id);
 | 
					                            var id = reader.ReadElementContentAsString();
 | 
				
			||||||
 | 
					                            if (!string.IsNullOrWhiteSpace(id))
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                item.SetProviderId(providerIdValue, id);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        else
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            reader.Skip();
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    else
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        reader.Skip();
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    break;
 | 
					                        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using CommonIO;
 | 
					using CommonIO;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Collections;
 | 
				
			||||||
using MediaBrowser.Controller.Configuration;
 | 
					using MediaBrowser.Controller.Configuration;
 | 
				
			||||||
using MediaBrowser.Controller.Entities;
 | 
					using MediaBrowser.Controller.Entities;
 | 
				
			||||||
using MediaBrowser.Controller.Library;
 | 
					using MediaBrowser.Controller.Library;
 | 
				
			||||||
@ -21,4 +22,17 @@ namespace MediaBrowser.Providers.Folders
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class ManualCollectionsFolderMetadataService : MetadataService<ManualCollectionsFolder, ItemLookupInfo>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        protected override void MergeData(MetadataResult<ManualCollectionsFolder> source, MetadataResult<ManualCollectionsFolder> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public ManualCollectionsFolderMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@
 | 
				
			|||||||
using MediaBrowser.Controller.Entities;
 | 
					using MediaBrowser.Controller.Entities;
 | 
				
			||||||
using System.IO;
 | 
					using System.IO;
 | 
				
			||||||
using CommonIO;
 | 
					using CommonIO;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Collections;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MediaBrowser.Server.Implementations.Collections
 | 
					namespace MediaBrowser.Server.Implementations.Collections
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -53,11 +53,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
 | 
					        public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            if (mediaSource.Path.IndexOf("m3u8", StringComparison.OrdinalIgnoreCase) != -1)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                await RecordWithoutTempFile(mediaSource, targetFile, duration, onStarted, cancellationToken)
 | 
				
			||||||
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var tempfile = Path.Combine(_appPaths.TranscodingTempPath, Guid.NewGuid().ToString("N") + ".ts");
 | 
					            var tempfile = Path.Combine(_appPaths.TranscodingTempPath, Guid.NewGuid().ToString("N") + ".ts");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await RecordInternal(mediaSource, tempfile, targetFile, duration, onStarted, cancellationToken)
 | 
					                await RecordWithTempFile(mediaSource, tempfile, targetFile, duration, onStarted, cancellationToken)
 | 
				
			||||||
                        .ConfigureAwait(false);
 | 
					                        .ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            finally
 | 
					            finally
 | 
				
			||||||
@ -73,7 +81,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task RecordInternal(MediaSourceInfo mediaSource, string tempFile, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
 | 
					        private async Task RecordWithoutTempFile(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var durationToken = new CancellationTokenSource(duration);
 | 
				
			||||||
 | 
					            cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await RecordFromFile(mediaSource, mediaSource.Path, targetFile, duration, onStarted, cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _logger.Info("Recording completed to file {0}", targetFile);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async Task RecordWithTempFile(MediaSourceInfo mediaSource, string tempFile, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var httpRequestOptions = new HttpRequestOptions()
 | 
					            var httpRequestOptions = new HttpRequestOptions()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
				
			|||||||
@ -124,7 +124,6 @@
 | 
				
			|||||||
    <Compile Include="Channels\RefreshChannelsScheduledTask.cs" />
 | 
					    <Compile Include="Channels\RefreshChannelsScheduledTask.cs" />
 | 
				
			||||||
    <Compile Include="Collections\CollectionManager.cs" />
 | 
					    <Compile Include="Collections\CollectionManager.cs" />
 | 
				
			||||||
    <Compile Include="Collections\CollectionsDynamicFolder.cs" />
 | 
					    <Compile Include="Collections\CollectionsDynamicFolder.cs" />
 | 
				
			||||||
    <Compile Include="Collections\ManualCollectionsFolder.cs" />
 | 
					 | 
				
			||||||
    <Compile Include="Collections\CollectionImageProvider.cs" />
 | 
					    <Compile Include="Collections\CollectionImageProvider.cs" />
 | 
				
			||||||
    <Compile Include="Configuration\ServerConfigurationManager.cs" />
 | 
					    <Compile Include="Configuration\ServerConfigurationManager.cs" />
 | 
				
			||||||
    <Compile Include="Connect\ConnectData.cs" />
 | 
					    <Compile Include="Connect\ConnectData.cs" />
 | 
				
			||||||
 | 
				
			|||||||
@ -149,16 +149,16 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
 | 
				
			|||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        // Add some time for the first chapter to make sure we don't end up with a black image
 | 
					 | 
				
			||||||
                        var time = chapter.StartPositionTicks == 0 ? TimeSpan.FromTicks(Math.Min(FirstChapterTicks, video.RunTimeTicks ?? 0)) : TimeSpan.FromTicks(chapter.StartPositionTicks);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        var protocol = MediaProtocol.File;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, video.PlayableStreamFileNames);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        try
 | 
					                        try
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
							_fileSystem.CreateDirectory(Path.GetDirectoryName(path));
 | 
					                            // Add some time for the first chapter to make sure we don't end up with a black image
 | 
				
			||||||
 | 
					                            var time = chapter.StartPositionTicks == 0 ? TimeSpan.FromTicks(Math.Min(FirstChapterTicks, video.RunTimeTicks ?? 0)) : TimeSpan.FromTicks(chapter.StartPositionTicks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            var protocol = MediaProtocol.File;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, video.PlayableStreamFileNames);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            var tempFile = await _encoder.ExtractVideoImage(inputPath, protocol, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false);
 | 
					                            var tempFile = await _encoder.ExtractVideoImage(inputPath, protocol, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
                            File.Copy(tempFile, path, true);
 | 
					                            File.Copy(tempFile, path, true);
 | 
				
			||||||
@ -178,7 +178,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
 | 
				
			|||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        catch (Exception ex)
 | 
					                        catch (Exception ex)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            _logger.ErrorException("Error extracting chapter images for {0}", ex, string.Join(",", inputPath));
 | 
					                            _logger.ErrorException("Error extracting chapter images for {0}", ex, string.Join(",", video.Path));
 | 
				
			||||||
                            success = false;
 | 
					                            success = false;
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,10 @@ using System.IO;
 | 
				
			|||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using CommonIO;
 | 
					using CommonIO;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Collections;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Entities.Movies;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Library;
 | 
				
			||||||
 | 
					using MediaBrowser.Model.Querying;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MediaBrowser.Server.Implementations.UserViews
 | 
					namespace MediaBrowser.Server.Implementations.UserViews
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -109,4 +113,62 @@ namespace MediaBrowser.Server.Implementations.UserViews
 | 
				
			|||||||
            return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false);
 | 
					            return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class ManualCollectionFolderImageProvider : BaseDynamicImageProvider<ManualCollectionsFolder>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly ILibraryManager _libraryManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public ManualCollectionFolderImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) : base(fileSystem, providerManager, applicationPaths, imageProcessor)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _libraryManager = libraryManager;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override IEnumerable<ImageType> GetSupportedImages(IHasImages item)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new List<ImageType>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ImageType.Primary
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected override async Task<List<BaseItem>> GetItemsWithImages(IHasImages item)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var view = (ManualCollectionsFolder)item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var recursive = !new[] { CollectionType.Playlists, CollectionType.Channels }.Contains(view.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var items = _libraryManager.GetItemList(new InternalItemsQuery
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Recursive = recursive,
 | 
				
			||||||
 | 
					                IncludeItemTypes = new[] { typeof(BoxSet).Name },
 | 
				
			||||||
 | 
					                Limit = 20,
 | 
				
			||||||
 | 
					                SortBy = new[] { ItemSortBy.Random }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected override bool Supports(IHasImages item)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return item is ManualCollectionsFolder;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected override async Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (imageType == ImageType.Primary)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (itemsWithImages.Count == 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return null;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -755,9 +755,6 @@
 | 
				
			|||||||
    <Content Include="dashboard-ui\reports.html">
 | 
					    <Content Include="dashboard-ui\reports.html">
 | 
				
			||||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
					      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
				
			||||||
    </Content>
 | 
					    </Content>
 | 
				
			||||||
    <Content Include="dashboard-ui\livetvrecordinglist.html">
 | 
					 | 
				
			||||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
					 | 
				
			||||||
    </Content>
 | 
					 | 
				
			||||||
    <Content Include="dashboard-ui\livetvseriestimer.html">
 | 
					    <Content Include="dashboard-ui\livetvseriestimer.html">
 | 
				
			||||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
					      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
				
			||||||
    </Content>
 | 
					    </Content>
 | 
				
			||||||
@ -944,9 +941,6 @@
 | 
				
			|||||||
    <Content Include="dashboard-ui\scripts\livetvchannel.js">
 | 
					    <Content Include="dashboard-ui\scripts\livetvchannel.js">
 | 
				
			||||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
					      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
				
			||||||
    </Content>
 | 
					    </Content>
 | 
				
			||||||
    <Content Include="dashboard-ui\scripts\livetvrecordinglist.js">
 | 
					 | 
				
			||||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
					 | 
				
			||||||
    </Content>
 | 
					 | 
				
			||||||
    <Content Include="dashboard-ui\scripts\livetvseriestimer.js">
 | 
					    <Content Include="dashboard-ui\scripts\livetvseriestimer.js">
 | 
				
			||||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
					      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
				
			||||||
    </Content>
 | 
					    </Content>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user