fixes #797 - Determine mpeg2ts timestamp info

This commit is contained in:
Luke Pulverenti 2014-04-24 22:00:19 -04:00
parent 725e1a1509
commit eca1ba0b12
21 changed files with 125 additions and 55 deletions

View File

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

View File

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

View File

@ -2,6 +2,7 @@
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.Model.Dlna;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using System; using System;
using System.Collections; using System.Collections;
@ -11,6 +12,7 @@ using System.Linq;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Controller.Entities namespace MediaBrowser.Controller.Entities
{ {
@ -31,6 +33,12 @@ namespace MediaBrowser.Controller.Entities
public string Container { get; set; } public string Container { get; set; }
public int? TotalBitrate { 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() public Video()
{ {
PlayableStreamFileNames = new List<string>(); PlayableStreamFileNames = new List<string>();

View File

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

View File

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

View File

@ -1,9 +0,0 @@

namespace MediaBrowser.Model.Configuration
{
public enum ManualLoginCategory
{
Mobile,
MediaBrowserTheater
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,6 +4,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Model.Dlna namespace MediaBrowser.Model.Dlna
{ {
@ -285,7 +286,7 @@ namespace MediaBrowser.Model.Dlna
var audioBitrate = audioStream == null ? null : audioStream.BitRate; var audioBitrate = audioStream == null ? null : audioStream.BitRate;
var audioChannels = audioStream == null ? null : audioStream.Channels; 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; var packetLength = videoStream == null ? null : videoStream.PacketLength;
// Check container conditions // Check container conditions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,11 +1,13 @@
using DvdLib.Ifo; using DvdLib.Ifo;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
@ -33,6 +35,7 @@ namespace MediaBrowser.Providers.MediaInfo
private readonly IApplicationPaths _appPaths; private readonly IApplicationPaths _appPaths;
private readonly IJsonSerializer _json; private readonly IJsonSerializer _json;
private readonly IEncodingManager _encodingManager; private readonly IEncodingManager _encodingManager;
private readonly IFileSystem _fileSystem;
private readonly CultureInfo _usCulture = new CultureInfo("en-US"); 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); video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);
ExtractTimestamp(video);
await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions
{ {
Chapters = chapters, 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) private void FetchFromDvdLib(Video item, IIsoMount mount)
{ {
var path = mount == null ? item.Path : mount.MountedPath; var path = mount == null ? item.Path : mount.MountedPath;

View File

@ -1237,7 +1237,8 @@ namespace MediaBrowser.Server.Implementations.Dto
VideoType = i.VideoType, VideoType = i.VideoType,
Container = i.Container, Container = i.Container,
Size = i.Size, 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)) if (string.IsNullOrEmpty(info.Container))

View File

@ -276,7 +276,7 @@
"HeaderPleaseSignIn": "Please sign in", "HeaderPleaseSignIn": "Please sign in",
"LabelUser": "User:", "LabelUser": "User:",
"LabelPassword": "Password:", "LabelPassword": "Password:",
"ButtonManualLogin": "Manual Login:", "ButtonManualLogin": "Manual Login",
"PasswordLocalhostMessage": "Passwords are not required when logging in from localhost.", "PasswordLocalhostMessage": "Passwords are not required when logging in from localhost.",
"TabGuide": "Guide", "TabGuide": "Guide",
"TabChannels": "Channels", "TabChannels": "Channels",
@ -545,5 +545,14 @@
"LabelDefaultUser": "Default user:", "LabelDefaultUser": "Default user:",
"LabelDefaultUserHelp": "Determines which user library should be displayed on connected devices. This can be overridden for each device using profiles.", "LabelDefaultUserHelp": "Determines which user library should be displayed on connected devices. This can be overridden for each device using profiles.",
"TitleDlna": "DLNA", "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"
} }