Browse Source

Merge pull request #20 from jellyfin/master

nightly
artiume 5 years ago
parent
commit
eb67117b83

+ 12 - 12
Emby.Server.Implementations/ApplicationHost.cs

@@ -755,7 +755,18 @@ namespace Emby.Server.Implementations
 
 
             serviceCollection.AddSingleton(UserManager);
             serviceCollection.AddSingleton(UserManager);
 
 
-            LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager);
+            MediaEncoder = new MediaBrowser.MediaEncoding.Encoder.MediaEncoder(
+                LoggerFactory.CreateLogger<MediaBrowser.MediaEncoding.Encoder.MediaEncoder>(),
+                ServerConfigurationManager,
+                FileSystemManager,
+                ProcessFactory,
+                LocalizationManager,
+                () => SubtitleEncoder,
+                _configuration,
+                StartupOptions.FFmpegPath);
+            serviceCollection.AddSingleton(MediaEncoder);
+
+            LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager, MediaEncoder);
             serviceCollection.AddSingleton(LibraryManager);
             serviceCollection.AddSingleton(LibraryManager);
 
 
             var musicManager = new MusicManager(LibraryManager);
             var musicManager = new MusicManager(LibraryManager);
@@ -833,17 +844,6 @@ namespace Emby.Server.Implementations
             ChapterManager = new ChapterManager(LibraryManager, LoggerFactory, ServerConfigurationManager, ItemRepository);
             ChapterManager = new ChapterManager(LibraryManager, LoggerFactory, ServerConfigurationManager, ItemRepository);
             serviceCollection.AddSingleton(ChapterManager);
             serviceCollection.AddSingleton(ChapterManager);
 
 
-            MediaEncoder = new MediaBrowser.MediaEncoding.Encoder.MediaEncoder(
-                LoggerFactory.CreateLogger<MediaBrowser.MediaEncoding.Encoder.MediaEncoder>(),
-                ServerConfigurationManager,
-                FileSystemManager,
-                ProcessFactory,
-                LocalizationManager,
-                () => SubtitleEncoder,
-                _configuration,
-                StartupOptions.FFmpegPath);
-            serviceCollection.AddSingleton(MediaEncoder);
-
             EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager);
             EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager);
             serviceCollection.AddSingleton(EncodingManager);
             serviceCollection.AddSingleton(EncodingManager);
 
 

+ 38 - 1
Emby.Server.Implementations/Library/LibraryManager.cs

@@ -29,11 +29,13 @@ using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Controller.Sorting;
 using MediaBrowser.Controller.Sorting;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
@@ -141,6 +143,7 @@ namespace Emby.Server.Implementations.Library
         public bool IsScanRunning { get; private set; }
         public bool IsScanRunning { get; private set; }
 
 
         private IServerApplicationHost _appHost;
         private IServerApplicationHost _appHost;
+        private readonly IMediaEncoder _mediaEncoder;
 
 
         /// <summary>
         /// <summary>
         /// The _library items cache
         /// The _library items cache
@@ -174,7 +177,8 @@ namespace Emby.Server.Implementations.Library
             Func<ILibraryMonitor> libraryMonitorFactory,
             Func<ILibraryMonitor> libraryMonitorFactory,
             IFileSystem fileSystem,
             IFileSystem fileSystem,
             Func<IProviderManager> providerManagerFactory,
             Func<IProviderManager> providerManagerFactory,
-            Func<IUserViewManager> userviewManager)
+            Func<IUserViewManager> userviewManager,
+            IMediaEncoder mediaEncoder)
         {
         {
             _appHost = appHost;
             _appHost = appHost;
             _logger = loggerFactory.CreateLogger(nameof(LibraryManager));
             _logger = loggerFactory.CreateLogger(nameof(LibraryManager));
@@ -186,6 +190,7 @@ namespace Emby.Server.Implementations.Library
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
             _providerManagerFactory = providerManagerFactory;
             _providerManagerFactory = providerManagerFactory;
             _userviewManager = userviewManager;
             _userviewManager = userviewManager;
+            _mediaEncoder = mediaEncoder;
 
 
             _libraryItemsCache = new ConcurrentDictionary<Guid, BaseItem>();
             _libraryItemsCache = new ConcurrentDictionary<Guid, BaseItem>();
 
 
@@ -2408,6 +2413,38 @@ namespace Emby.Server.Implementations.Library
                 episodeInfo = new Naming.TV.EpisodeInfo();
                 episodeInfo = new Naming.TV.EpisodeInfo();
             }
             }
 
 
+            try
+            {
+                var libraryOptions = GetLibraryOptions(episode);
+                if (libraryOptions.EnableEmbeddedEpisodeInfos && string.Equals(episodeInfo.Container, "mp4", StringComparison.OrdinalIgnoreCase))
+                {
+                    // Read from metadata
+                    var mediaInfo = _mediaEncoder.GetMediaInfo(new MediaInfoRequest
+                    {
+                        MediaSource = episode.GetMediaSources(false)[0],
+                        MediaType = DlnaProfileType.Video
+                    }, CancellationToken.None).GetAwaiter().GetResult();
+                    if (mediaInfo.ParentIndexNumber > 0)
+                    {
+                        episodeInfo.SeasonNumber = mediaInfo.ParentIndexNumber;
+                    }
+
+                    if (mediaInfo.IndexNumber > 0)
+                    {
+                        episodeInfo.EpisodeNumber = mediaInfo.IndexNumber;
+                    }
+
+                    if (!string.IsNullOrEmpty(mediaInfo.ShowName))
+                    {
+                        episodeInfo.SeriesName = mediaInfo.ShowName;
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "Error reading the episode informations with ffprobe. Episode: {EpisodeInfo}", episodeInfo.Path);
+            }
+
             var changed = false;
             var changed = false;
 
 
             if (episodeInfo.IsByDate)
             if (episodeInfo.IsByDate)

+ 14 - 1
Emby.Server.Implementations/Localization/Core/es_DO.json

@@ -1 +1,14 @@
-{}
+{
+    "Channels": "Canales",
+    "Books": "Libros",
+    "Albums": "Álbumes",
+    "Collections": "Colecciones",
+    "Artists": "Artistas",
+    "DeviceOnlineWithName": "{0} está conectado",
+    "DeviceOfflineWithName": "{0} ha desconectado",
+    "ChapterNameValue": "Capítulo {0}",
+    "CameraImageUploadedFrom": "Se ha subido una nueva imagen de cámara desde {0}",
+    "AuthenticationSucceededWithUserName": "{0} autenticado con éxito",
+    "Application": "Aplicación",
+    "AppDeviceValues": "App: {0}, Dispositivo: {1}"
+}

+ 2 - 2
Emby.Server.Implementations/Localization/Core/zh-CN.json

@@ -89,8 +89,8 @@
     "UserOnlineFromDevice": "{0} 在线,来自 {1}",
     "UserOnlineFromDevice": "{0} 在线,来自 {1}",
     "UserPasswordChangedWithName": "已为用户 {0} 更改密码",
     "UserPasswordChangedWithName": "已为用户 {0} 更改密码",
     "UserPolicyUpdatedWithName": "用户协议已经被更新为 {0}",
     "UserPolicyUpdatedWithName": "用户协议已经被更新为 {0}",
-    "UserStartedPlayingItemWithValues": "{0} 已开始播放 {1}",
-    "UserStoppedPlayingItemWithValues": "{0} 已停止播放 {1}",
+    "UserStartedPlayingItemWithValues": "{0} 已在 {2} 上开始播放 {1}",
+    "UserStoppedPlayingItemWithValues": "{0} 已在 {2} 上停止播放 {1}",
     "ValueHasBeenAddedToLibrary": "{0} 已添加至您的媒体库中",
     "ValueHasBeenAddedToLibrary": "{0} 已添加至您的媒体库中",
     "ValueSpecialEpisodeName": "特典 - {0}",
     "ValueSpecialEpisodeName": "特典 - {0}",
     "VersionNumber": "版本 {0}"
     "VersionNumber": "版本 {0}"

+ 87 - 87
Emby.Server.Implementations/Localization/Core/zh-HK.json

@@ -1,97 +1,97 @@
 {
 {
-    "Albums": "Albums",
-    "AppDeviceValues": "App: {0}, Device: {1}",
-    "Application": "Application",
+    "Albums": "專輯",
+    "AppDeviceValues": "軟體: {0}, 設備: {1}",
+    "Application": "應用程式",
     "Artists": "藝人",
     "Artists": "藝人",
-    "AuthenticationSucceededWithUserName": "{0} successfully authenticated",
-    "Books": "Books",
-    "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
-    "Channels": "Channels",
-    "ChapterNameValue": "Chapter {0}",
-    "Collections": "Collections",
-    "DeviceOfflineWithName": "{0} has disconnected",
-    "DeviceOnlineWithName": "{0} is connected",
-    "FailedLoginAttemptWithUserName": "Failed login attempt from {0}",
-    "Favorites": "Favorites",
-    "Folders": "Folders",
-    "Genres": "Genres",
-    "HeaderAlbumArtists": "Album Artists",
-    "HeaderCameraUploads": "Camera Uploads",
-    "HeaderContinueWatching": "Continue Watching",
-    "HeaderFavoriteAlbums": "Favorite Albums",
-    "HeaderFavoriteArtists": "Favorite Artists",
-    "HeaderFavoriteEpisodes": "Favorite Episodes",
-    "HeaderFavoriteShows": "Favorite Shows",
-    "HeaderFavoriteSongs": "Favorite Songs",
-    "HeaderLiveTV": "Live TV",
-    "HeaderNextUp": "Next Up",
-    "HeaderRecordingGroups": "Recording Groups",
-    "HomeVideos": "Home videos",
-    "Inherit": "Inherit",
-    "ItemAddedWithName": "{0} was added to the library",
-    "ItemRemovedWithName": "{0} was removed from the library",
-    "LabelIpAddressValue": "Ip address: {0}",
-    "LabelRunningTimeValue": "Running time: {0}",
-    "Latest": "Latest",
-    "MessageApplicationUpdated": "Jellyfin Server has been updated",
-    "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}",
-    "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated",
-    "MessageServerConfigurationUpdated": "Server configuration has been updated",
+    "AuthenticationSucceededWithUserName": "{0} 授權成功",
+    "Books": "圖書",
+    "CameraImageUploadedFrom": "{0} 成功上傳一張新相片",
+    "Channels": "頻道",
+    "ChapterNameValue": "章節 {0}",
+    "Collections": "合輯",
+    "DeviceOfflineWithName": "{0} 已經斷開連結",
+    "DeviceOnlineWithName": "{0} 已經連接",
+    "FailedLoginAttemptWithUserName": "來自 {0} 的失敗登入嘗試",
+    "Favorites": "我的最愛",
+    "Folders": "檔案夾",
+    "Genres": "風格",
+    "HeaderAlbumArtists": "專輯藝術家",
+    "HeaderCameraUploads": "相機上載",
+    "HeaderContinueWatching": "繼續觀看",
+    "HeaderFavoriteAlbums": "最愛專輯",
+    "HeaderFavoriteArtists": "最愛藝術家",
+    "HeaderFavoriteEpisodes": "最愛的劇集",
+    "HeaderFavoriteShows": "最愛的節目",
+    "HeaderFavoriteSongs": "最愛的歌曲",
+    "HeaderLiveTV": "電視直播",
+    "HeaderNextUp": "接下來",
+    "HeaderRecordingGroups": "錄製組",
+    "HomeVideos": "家庭影片",
+    "Inherit": "繼承",
+    "ItemAddedWithName": "{0} 已添加至媒體庫",
+    "ItemRemovedWithName": "{0} 已從媒體庫移除",
+    "LabelIpAddressValue": "IP 地址: {0}",
+    "LabelRunningTimeValue": "運行時間: {0}",
+    "Latest": "最新",
+    "MessageApplicationUpdated": "Jellyfin Server 已更新",
+    "MessageApplicationUpdatedTo": "Jellyfin 伺服器已更新至 {0}",
+    "MessageNamedServerConfigurationUpdatedWithValue": "伺服器設定 {0} 部分已更新",
+    "MessageServerConfigurationUpdated": "伺服器設定已經更新",
     "MixedContent": "Mixed content",
     "MixedContent": "Mixed content",
-    "Movies": "Movies",
-    "Music": "Music",
-    "MusicVideos": "Music videos",
-    "NameInstallFailed": "{0} installation failed",
-    "NameSeasonNumber": "Season {0}",
-    "NameSeasonUnknown": "Season Unknown",
-    "NewVersionIsAvailable": "A new version of Jellyfin Server is available for download.",
-    "NotificationOptionApplicationUpdateAvailable": "Application update available",
-    "NotificationOptionApplicationUpdateInstalled": "Application update installed",
-    "NotificationOptionAudioPlayback": "Audio playback started",
-    "NotificationOptionAudioPlaybackStopped": "Audio playback stopped",
-    "NotificationOptionCameraImageUploaded": "Camera image uploaded",
-    "NotificationOptionInstallationFailed": "Installation failure",
-    "NotificationOptionNewLibraryContent": "New content added",
-    "NotificationOptionPluginError": "Plugin failure",
-    "NotificationOptionPluginInstalled": "Plugin installed",
-    "NotificationOptionPluginUninstalled": "Plugin uninstalled",
-    "NotificationOptionPluginUpdateInstalled": "Plugin update installed",
-    "NotificationOptionServerRestartRequired": "Server restart required",
-    "NotificationOptionTaskFailed": "Scheduled task failure",
-    "NotificationOptionUserLockedOut": "User locked out",
-    "NotificationOptionVideoPlayback": "Video playback started",
-    "NotificationOptionVideoPlaybackStopped": "Video playback stopped",
-    "Photos": "Photos",
-    "Playlists": "Playlists",
+    "Movies": "電影",
+    "Music": "音樂",
+    "MusicVideos": "音樂MV",
+    "NameInstallFailed": "{0} 安裝失敗",
+    "NameSeasonNumber": "第 {0} 季",
+    "NameSeasonUnknown": "未知季數",
+    "NewVersionIsAvailable": "新版本的 Jellyfin 伺服器可供下載。",
+    "NotificationOptionApplicationUpdateAvailable": "有可用的應用程式更新",
+    "NotificationOptionApplicationUpdateInstalled": "應用程式已更新",
+    "NotificationOptionAudioPlayback": "開始播放音頻",
+    "NotificationOptionAudioPlaybackStopped": "已停止播放音頻",
+    "NotificationOptionCameraImageUploaded": "相機相片已上傳",
+    "NotificationOptionInstallationFailed": "安裝失敗",
+    "NotificationOptionNewLibraryContent": "已添加新内容",
+    "NotificationOptionPluginError": "擴充元件錯誤",
+    "NotificationOptionPluginInstalled": "擴充元件已安裝",
+    "NotificationOptionPluginUninstalled": "擴充元件已移除",
+    "NotificationOptionPluginUpdateInstalled": "擴充元件更新已安裝",
+    "NotificationOptionServerRestartRequired": "伺服器需要重啓",
+    "NotificationOptionTaskFailed": "計劃任務失敗",
+    "NotificationOptionUserLockedOut": "用家已鎖定",
+    "NotificationOptionVideoPlayback": "開始播放視頻",
+    "NotificationOptionVideoPlaybackStopped": "已停止播放視頻",
+    "Photos": "相片",
+    "Playlists": "播放清單",
     "Plugin": "Plugin",
     "Plugin": "Plugin",
-    "PluginInstalledWithName": "{0} was installed",
-    "PluginUninstalledWithName": "{0} was uninstalled",
-    "PluginUpdatedWithName": "{0} was updated",
+    "PluginInstalledWithName": "已安裝 {0}",
+    "PluginUninstalledWithName": "已移除 {0}",
+    "PluginUpdatedWithName": "已更新 {0}",
     "ProviderValue": "Provider: {0}",
     "ProviderValue": "Provider: {0}",
-    "ScheduledTaskFailedWithName": "{0} failed",
-    "ScheduledTaskStartedWithName": "{0} started",
-    "ServerNameNeedsToBeRestarted": "{0} needs to be restarted",
-    "Shows": "Shows",
-    "Songs": "Songs",
-    "StartupEmbyServerIsLoading": "Jellyfin Server is loading. Please try again shortly.",
+    "ScheduledTaskFailedWithName": "{0} 任務失敗",
+    "ScheduledTaskStartedWithName": "{0} 任務開始",
+    "ServerNameNeedsToBeRestarted": "{0} 需要重啓",
+    "Shows": "節目",
+    "Songs": "歌曲",
+    "StartupEmbyServerIsLoading": "Jellyfin 伺服器載入中,請稍後再試。",
     "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
     "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
-    "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
-    "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}",
-    "Sync": "Sync",
+    "SubtitleDownloadFailureFromForItem": "無法從 {0} 下載 {1} 的字幕",
+    "SubtitlesDownloadedForItem": "已為 {0} 下載了字幕",
+    "Sync": "同步",
     "System": "System",
     "System": "System",
-    "TvShows": "TV Shows",
+    "TvShows": "電視節目",
     "User": "User",
     "User": "User",
-    "UserCreatedWithName": "User {0} has been created",
-    "UserDeletedWithName": "User {0} has been deleted",
-    "UserDownloadingItemWithValues": "{0} is downloading {1}",
-    "UserLockedOutWithName": "User {0} has been locked out",
-    "UserOfflineFromDevice": "{0} has disconnected from {1}",
-    "UserOnlineFromDevice": "{0} is online from {1}",
-    "UserPasswordChangedWithName": "Password has been changed for user {0}",
-    "UserPolicyUpdatedWithName": "User policy has been updated for {0}",
-    "UserStartedPlayingItemWithValues": "{0} is playing {1} on {2}",
-    "UserStoppedPlayingItemWithValues": "{0} has finished playing {1} on {2}",
-    "ValueHasBeenAddedToLibrary": "{0} has been added to your media library",
-    "ValueSpecialEpisodeName": "Special - {0}",
+    "UserCreatedWithName": "用家 {0} 已創建",
+    "UserDeletedWithName": "用家 {0} 已移除",
+    "UserDownloadingItemWithValues": "{0} 正在下載 {1}",
+    "UserLockedOutWithName": "用家 {0} 已被鎖定",
+    "UserOfflineFromDevice": "{0} 已從 {1} 斷開",
+    "UserOnlineFromDevice": "{0} 已連綫,來自 {1}",
+    "UserPasswordChangedWithName": "用家 {0} 的密碼已變更",
+    "UserPolicyUpdatedWithName": "用戶協議已被更新為 {0}",
+    "UserStartedPlayingItemWithValues": "{0} 正在 {2} 上播放 {1}",
+    "UserStoppedPlayingItemWithValues": "{0} 已在 {2} 上停止播放 {1}",
+    "ValueHasBeenAddedToLibrary": "{0} 已添加到你的媒體庫",
+    "ValueSpecialEpisodeName": "特典 - {0}",
     "VersionNumber": "版本{0}"
     "VersionNumber": "版本{0}"
 }
 }

+ 1 - 1
Emby.Server.Implementations/Localization/Core/zh-TW.json

@@ -50,7 +50,7 @@
     "NotificationOptionCameraImageUploaded": "相機相片已上傳",
     "NotificationOptionCameraImageUploaded": "相機相片已上傳",
     "NotificationOptionInstallationFailed": "安裝失敗",
     "NotificationOptionInstallationFailed": "安裝失敗",
     "NotificationOptionNewLibraryContent": "已新增新內容",
     "NotificationOptionNewLibraryContent": "已新增新內容",
-    "NotificationOptionPluginError": "擴充元件安裝失敗",
+    "NotificationOptionPluginError": "擴充元件錯誤",
     "NotificationOptionPluginInstalled": "擴充元件已安裝",
     "NotificationOptionPluginInstalled": "擴充元件已安裝",
     "NotificationOptionPluginUninstalled": "擴充元件已移除",
     "NotificationOptionPluginUninstalled": "擴充元件已移除",
     "NotificationOptionPluginUpdateInstalled": "已更新擴充元件",
     "NotificationOptionPluginUpdateInstalled": "已更新擴充元件",

+ 3 - 0
MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs

@@ -112,6 +112,9 @@ namespace MediaBrowser.MediaEncoding.Probing
                 info.Name = title;
                 info.Name = title;
             }
             }
 
 
+            info.IndexNumber = FFProbeHelpers.GetDictionaryNumericValue(tags, "episode_sort");
+            info.ParentIndexNumber = FFProbeHelpers.GetDictionaryNumericValue(tags, "season_number");
+            info.ShowName = FFProbeHelpers.GetDictionaryValue(tags, "show_name");
             info.ProductionYear = FFProbeHelpers.GetDictionaryNumericValue(tags, "date");
             info.ProductionYear = FFProbeHelpers.GetDictionaryNumericValue(tags, "date");
 
 
             // Several different forms of retaildate
             // Several different forms of retaildate

+ 1 - 0
MediaBrowser.Model/Configuration/LibraryOptions.cs

@@ -21,6 +21,7 @@ namespace MediaBrowser.Model.Configuration
         public bool ImportMissingEpisodes { get; set; }
         public bool ImportMissingEpisodes { get; set; }
         public bool EnableAutomaticSeriesGrouping { get; set; }
         public bool EnableAutomaticSeriesGrouping { get; set; }
         public bool EnableEmbeddedTitles { get; set; }
         public bool EnableEmbeddedTitles { get; set; }
+        public bool EnableEmbeddedEpisodeInfos { get; set; }
 
 
         public int AutomaticRefreshIntervalDays { get; set; }
         public int AutomaticRefreshIntervalDays { get; set; }
 
 

+ 1 - 0
MediaBrowser.Model/MediaInfo/MediaInfo.cs

@@ -36,6 +36,7 @@ namespace MediaBrowser.Model.MediaInfo
         /// <value>The studios.</value>
         /// <value>The studios.</value>
         public string[] Studios { get; set; }
         public string[] Studios { get; set; }
         public string[] Genres { get; set; }
         public string[] Genres { get; set; }
+        public string ShowName { get; set; }
         public int? IndexNumber { get; set; }
         public int? IndexNumber { get; set; }
         public int? ParentIndexNumber { get; set; }
         public int? ParentIndexNumber { get; set; }
         public int? ProductionYear { get; set; }
         public int? ProductionYear { get; set; }