Przeglądaj źródła

fixes #797 - Determine mpeg2ts timestamp info

Luke Pulverenti 11 lat temu
rodzic
commit
eca1ba0b12

+ 3 - 0
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -1435,6 +1435,9 @@ namespace MediaBrowser.Api.Playback
                     state.PlayableStreamFileNames = video.PlayableStreamFileNames == null
                         ? new List<string>()
                         : video.PlayableStreamFileNames.ToList();
+
+                    state.DeInterlace = string.Equals(video.Container, "wtv", StringComparison.OrdinalIgnoreCase);
+                    state.InputTimestamp = video.Timestamp;
                 }
 
                 state.RunTimeTicks = item.RunTimeTicks;

+ 11 - 6
MediaBrowser.Api/Playback/StreamState.cs

@@ -10,6 +10,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Threading;
+using MediaBrowser.Model.MediaInfo;
 
 namespace MediaBrowser.Api.Playback
 {
@@ -26,7 +27,7 @@ namespace MediaBrowser.Api.Playback
         {
             get { return Request as VideoStreamRequest; }
         }
-        
+
         /// <summary>
         /// Gets or sets the log file stream.
         /// </summary>
@@ -77,19 +78,21 @@ namespace MediaBrowser.Api.Playback
 
         public string InputAudioSync { get; set; }
         public string InputVideoSync { get; set; }
- 
+
         public bool DeInterlace { get; set; }
         public bool ReadInputAtNativeFramerate { get; set; }
         public string InputFormat { get; set; }
         public string InputVideoCodec { get; set; }
         public string InputAudioCodec { get; set; }
 
+        public TransportStreamTimestamp InputTimestamp { get; set; }
+
         public string MimeType { get; set; }
 
         public bool EstimateContentLength { get; set; }
         public bool EnableMpegtsM2TsMode { get; set; }
         public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
-        
+
         public string GetMimeType(string outputPath)
         {
             if (!string.IsNullOrEmpty(MimeType))
@@ -269,11 +272,13 @@ namespace MediaBrowser.Api.Playback
         {
             get
             {
-                var stream = VideoStream;
+                var defaultValue = string.Equals(OutputContainer, "m2ts", StringComparison.OrdinalIgnoreCase) ? 
+                    TransportStreamTimestamp.VALID : 
+                    TransportStreamTimestamp.NONE;
 
                 return !Request.Static
-                    ? TransportStreamTimestamp.VALID
-                    : stream == null ? TransportStreamTimestamp.VALID : stream.Timestamp;
+                    ? defaultValue
+                    : InputTimestamp;
             }
         }
 

+ 8 - 0
MediaBrowser.Controller/Entities/Video.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Resolvers;
+using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Entities;
 using System;
 using System.Collections;
@@ -11,6 +12,7 @@ using System.Linq;
 using System.Runtime.Serialization;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Model.MediaInfo;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -31,6 +33,12 @@ namespace MediaBrowser.Controller.Entities
         public string Container { get; set; }
         public int? TotalBitrate { get; set; }
 
+        /// <summary>
+        /// Gets or sets the timestamp.
+        /// </summary>
+        /// <value>The timestamp.</value>
+        public TransportStreamTimestamp Timestamp { get; set; }
+        
         public Video()
         {
             PlayableStreamFileNames = new List<string>();

+ 0 - 3
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -86,9 +86,6 @@
     <Compile Include="..\MediaBrowser.Model\Configuration\DlnaOptions.cs">
       <Link>Configuration\DlnaOptions.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Configuration\ManualLoginCategory.cs">
-      <Link>Configuration\ManualLoginCategory.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\Configuration\MetadataOptions.cs">
       <Link>Configuration\MetadataOptions.cs</Link>
     </Compile>

+ 0 - 3
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -73,9 +73,6 @@
     <Compile Include="..\MediaBrowser.Model\Configuration\DlnaOptions.cs">
       <Link>Configuration\DlnaOptions.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Configuration\ManualLoginCategory.cs">
-      <Link>Configuration\ManualLoginCategory.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\Configuration\MetadataOptions.cs">
       <Link>Configuration\MetadataOptions.cs</Link>
     </Compile>

+ 0 - 9
MediaBrowser.Model/Configuration/ManualLoginCategory.cs

@@ -1,9 +0,0 @@
-
-namespace MediaBrowser.Model.Configuration
-{
-    public enum ManualLoginCategory
-    {
-        Mobile,
-        MediaBrowserTheater
-    }
-}

+ 3 - 3
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -168,8 +168,6 @@ namespace MediaBrowser.Model.Configuration
         /// <value>The dashboard source path.</value>
         public string DashboardSourcePath { get; set; }
 
-        public ManualLoginCategory[] ManualLoginClients { get; set; }
-
         /// <summary>
         /// Gets or sets a value indicating whether [enable tv db updates].
         /// </summary>
@@ -178,6 +176,9 @@ namespace MediaBrowser.Model.Configuration
         public bool EnableTmdbUpdates { get; set; }
         public bool EnableFanArtUpdates { get; set; }
 
+        public bool RequireManualLoginForMobileApps { get; set; }
+        public bool RequireManualLoginForOtherApps { get; set; }
+
         /// <summary>
         /// Gets or sets the image saving convention.
         /// </summary>
@@ -256,7 +257,6 @@ namespace MediaBrowser.Model.Configuration
 
             EnableInternetProviders = true; //initial installs will need these
 
-            ManualLoginClients = new ManualLoginCategory[] { };
             PathSubstitutions = new PathSubstitution[] { };
 
             MetadataRefreshDays = 30;

+ 2 - 0
MediaBrowser.Model/Dlna/ConditionProcessor.cs

@@ -1,5 +1,7 @@
 using System;
 using System.Globalization;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.MediaInfo;
 
 namespace MediaBrowser.Model.Dlna
 {

+ 2 - 0
MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs

@@ -1,6 +1,8 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.MediaInfo;
 
 namespace MediaBrowser.Model.Dlna
 {

+ 2 - 0
MediaBrowser.Model/Dlna/DeviceProfile.cs

@@ -2,6 +2,8 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Xml.Serialization;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.MediaInfo;
 
 namespace MediaBrowser.Model.Dlna
 {

+ 0 - 7
MediaBrowser.Model/Dlna/MediaFormatProfile.cs

@@ -110,11 +110,4 @@ namespace MediaBrowser.Model.Dlna
         MPEG4_H263_3GPP_P0_L10_AMR,
         MPEG4_H263_MP4_P0_L10_AAC
     }
-
-    public enum TransportStreamTimestamp
-    {
-        NONE, 
-        ZERO, 
-        VALID
-    }
 }

+ 10 - 8
MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs

@@ -1,5 +1,7 @@
 using System;
 using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.MediaInfo;
 
 namespace MediaBrowser.Model.Dlna
 {
@@ -147,14 +149,14 @@ namespace MediaBrowser.Model.Dlna
             }
             else if (string.Equals(videoCodec, "mpeg4", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase))
             {
-                //  if (audioCodec == AudioCodec.AAC)
-                //    return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_AAC%s", cast(Object[])[ suffix ])));
-                //  if (audioCodec == AudioCodec.MP3)
-                //    return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_MPEG1_L3%s", cast(Object[])[ suffix ])));
-                //  if (audioCodec == AudioCodec.MP2)
-                //    return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_MPEG2_L2%s", cast(Object[])[ suffix ])));
-                //  if ((audioCodec is null) || (audioCodec == AudioCodec.AC3)) {
-                //    return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_AC3%s", cast(Object[])[ suffix ])));
+                if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+                    return new[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AAC{0}", suffix)) };
+                if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
+                    return new[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_MPEG1_L3{0}", suffix)) };
+                if (string.Equals(audioCodec, "mp2", StringComparison.OrdinalIgnoreCase))
+                    return new[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_MPEG2_L2{0}", suffix)) };
+                if (string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
+                    return new[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AC3{0}", suffix)) };
             }
 
             return new List<MediaFormatProfile>();

+ 2 - 1
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -4,6 +4,7 @@ using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
+using MediaBrowser.Model.MediaInfo;
 
 namespace MediaBrowser.Model.Dlna
 {
@@ -285,7 +286,7 @@ namespace MediaBrowser.Model.Dlna
             var audioBitrate = audioStream == null ? null : audioStream.BitRate;
             var audioChannels = audioStream == null ? null : audioStream.Channels;
 
-            var timestamp = videoStream == null ? TransportStreamTimestamp.NONE : videoStream.Timestamp;
+            var timestamp = videoStream == null ? TransportStreamTimestamp.NONE : mediaSource.Timestamp;
             var packetLength = videoStream == null ? null : videoStream.PacketLength;
 
             // Check container conditions

+ 7 - 4
MediaBrowser.Model/Dlna/StreamInfo.cs

@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
+using MediaBrowser.Model.MediaInfo;
 
 namespace MediaBrowser.Model.Dlna
 {
@@ -339,11 +340,13 @@ namespace MediaBrowser.Model.Dlna
         {
             get
             {
-                var stream = TargetVideoStream;
-
-                return !IsDirectStream
+                var defaultValue = string.Equals(Container, "m2ts", StringComparison.OrdinalIgnoreCase)
                     ? TransportStreamTimestamp.VALID
-                    : stream == null ? TransportStreamTimestamp.VALID : stream.Timestamp;
+                    : TransportStreamTimestamp.NONE;
+                
+                return !IsDirectStream
+                    ? defaultValue
+                    : MediaSource == null ? defaultValue : MediaSource.Timestamp;
             }
         }
 

+ 3 - 0
MediaBrowser.Model/Dto/MediaVersionInfo.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Model.Entities;
 using System.Collections.Generic;
+using MediaBrowser.Model.MediaInfo;
 
 namespace MediaBrowser.Model.Dto
 {
@@ -30,6 +31,8 @@ namespace MediaBrowser.Model.Dto
         
         public int? Bitrate { get; set; }
 
+        public TransportStreamTimestamp Timestamp { get; set; }
+        
         public MediaSourceInfo()
         {
             Formats = new List<string>();

+ 0 - 7
MediaBrowser.Model/Entities/MediaStream.cs

@@ -1,6 +1,5 @@
 using System.Collections.Generic;
 using System.Diagnostics;
-using MediaBrowser.Model.Dlna;
 
 namespace MediaBrowser.Model.Entities
 {
@@ -52,12 +51,6 @@ namespace MediaBrowser.Model.Entities
         /// <value>The length of the packet.</value>
         public int? PacketLength { get; set; }
 
-        /// <summary>
-        /// Gets or sets the timestamp.
-        /// </summary>
-        /// <value>The timestamp.</value>
-        public TransportStreamTimestamp Timestamp { get; set; }
-        
         /// <summary>
         /// Gets or sets the channels.
         /// </summary>

+ 0 - 1
MediaBrowser.Model/MediaBrowser.Model.csproj

@@ -62,7 +62,6 @@
     <Compile Include="Configuration\AutoOrganize.cs" />
     <Compile Include="Configuration\BaseApplicationConfiguration.cs" />
     <Compile Include="Configuration\DlnaOptions.cs" />
-    <Compile Include="Configuration\ManualLoginCategory.cs" />
     <Compile Include="Configuration\MetadataPlugin.cs" />
     <Compile Include="Configuration\MetadataOptions.cs" />
     <Compile Include="Configuration\ServerConfiguration.cs" />

+ 7 - 0
MediaBrowser.Model/MediaInfo/BlurayDiscInfo.cs

@@ -34,4 +34,11 @@ namespace MediaBrowser.Model.MediaInfo
         /// <value>The chapters.</value>
         public List<double> Chapters { get; set; }
     }
+
+    public enum TransportStreamTimestamp
+    {
+        NONE,
+        ZERO,
+        VALID
+    }
 }

+ 52 - 0
MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs

@@ -1,11 +1,13 @@
 using DvdLib.Ifo;
 using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
@@ -33,6 +35,7 @@ namespace MediaBrowser.Providers.MediaInfo
         private readonly IApplicationPaths _appPaths;
         private readonly IJsonSerializer _json;
         private readonly IEncodingManager _encodingManager;
+        private readonly IFileSystem _fileSystem;
 
         private readonly CultureInfo _usCulture = new CultureInfo("en-US");
 
@@ -215,6 +218,8 @@ namespace MediaBrowser.Providers.MediaInfo
 
             video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);
 
+            ExtractTimestamp(video);
+
             await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions
             {
                 Chapters = chapters,
@@ -568,6 +573,53 @@ namespace MediaBrowser.Providers.MediaInfo
             }
         }
 
+        private void ExtractTimestamp(Video video)
+        {
+            if (video.VideoType == VideoType.VideoFile)
+            {
+                if (string.Equals(video.Container, "mpeg2ts", StringComparison.OrdinalIgnoreCase) ||
+                    string.Equals(video.Container, "m2ts", StringComparison.OrdinalIgnoreCase) ||
+                    string.Equals(video.Container, "ts", StringComparison.OrdinalIgnoreCase))
+                {
+                    try
+                    {
+                        video.Timestamp = GetMpegTimestamp(video.Path);
+                    }
+                    catch (Exception ex)
+                    {
+                        _logger.ErrorException("Error extracting timestamp info from {0}", ex, video.Path);
+                    }
+                }
+            }
+        }
+
+        private TransportStreamTimestamp GetMpegTimestamp(string path)
+        {
+            var packetBuffer = new byte['Å'];
+
+            using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
+            {
+                fs.Read(packetBuffer, 0, packetBuffer.Length);
+            }
+
+            if (packetBuffer[0] == 71)
+            {
+                return TransportStreamTimestamp.NONE;
+            }
+
+            if ((packetBuffer[4] == 71) && (packetBuffer['Ä'] == 71))
+            {
+                if ((packetBuffer[0] == 0) && (packetBuffer[1] == 0) && (packetBuffer[2] == 0) && (packetBuffer[3] == 0))
+                {
+                    return TransportStreamTimestamp.ZERO;
+                }
+
+                return TransportStreamTimestamp.VALID;
+            }
+
+            return TransportStreamTimestamp.NONE;
+        }
+
         private void FetchFromDvdLib(Video item, IIsoMount mount)
         {
             var path = mount == null ? item.Path : mount.MountedPath;

+ 2 - 1
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -1237,7 +1237,8 @@ namespace MediaBrowser.Server.Implementations.Dto
                 VideoType = i.VideoType,
                 Container = i.Container,
                 Size = i.Size,
-                Formats = (i.FormatName ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList()
+                Formats = (i.FormatName ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(),
+                Timestamp = i.Timestamp
             };
 
             if (string.IsNullOrEmpty(info.Container))

+ 11 - 2
MediaBrowser.Server.Implementations/Localization/Server/server.json

@@ -276,7 +276,7 @@
 	"HeaderPleaseSignIn": "Please sign in",
 	"LabelUser": "User:",
 	"LabelPassword": "Password:",
-	"ButtonManualLogin": "Manual Login:",
+	"ButtonManualLogin": "Manual Login",
 	"PasswordLocalhostMessage": "Passwords are not required when logging in from localhost.",
 	"TabGuide": "Guide",
 	"TabChannels": "Channels",
@@ -545,5 +545,14 @@
 	"LabelDefaultUser": "Default user:",
 	"LabelDefaultUserHelp": "Determines which user library should be displayed on connected devices. This can be overridden for each device using profiles.",
 	"TitleDlna": "DLNA",
-	"HeaderServerSettings": "Server Settings"
+	"HeaderServerSettings": "Server Settings",
+	"LabelWeatherDisplayLocation": "Weather display location:",
+	"LabelWeatherDisplayLocationHelp": "US zip code / City, State, Country / City, Country",
+	"LabelWeatherDisplayUnit": "Weather display unit:",
+	"OptionCelsius": "Celsius",
+	"OptionFahrenheit": "Fahrenheit",
+	"HeaderRequireManualLogin": "Require manual username entry for:",
+	"HeaderRequireManualLoginHelp": "When disabled clients may present a login screen with a visual selection of users.",
+	"OptionOtherApps": "Other apps",
+	"OptionMobileApps": "Mobile apps"
 }