diff options
23 files changed, 237 insertions, 22 deletions
diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 4d003ca7c..3344bfcfe 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -472,6 +472,7 @@ namespace Emby.Dlna.Didl var targetAudioBitrate = streamInfo.TargetAudioBitrate; var targetSampleRate = streamInfo.TargetAudioSampleRate; var targetChannels = streamInfo.TargetAudioChannels; + var targetAudioBitDepth = streamInfo.TargetAudioBitDepth; if (targetChannels.HasValue) { @@ -492,7 +493,8 @@ namespace Emby.Dlna.Didl streamInfo.TargetAudioCodec, targetChannels, targetAudioBitrate, - targetSampleRate); + targetSampleRate, + targetAudioBitDepth); var filename = url.Substring(0, url.IndexOf('?')); @@ -505,6 +507,7 @@ namespace Emby.Dlna.Didl targetAudioBitrate, targetSampleRate, targetChannels, + targetAudioBitDepth, streamInfo.IsDirectStream, streamInfo.RunTimeTicks, streamInfo.TranscodeSeekInfo); diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index b09dba70c..82975ce22 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -587,7 +587,8 @@ namespace Emby.Dlna new DirectTvProfile(), new DishHopperJoeyProfile(), new DefaultProfile(), - new PopcornHourProfile() + new PopcornHourProfile(), + new MarantzProfile() }; foreach (var item in list) diff --git a/Emby.Dlna/Emby.Dlna.csproj b/Emby.Dlna/Emby.Dlna.csproj index cae5a9636..365774b0d 100644 --- a/Emby.Dlna/Emby.Dlna.csproj +++ b/Emby.Dlna/Emby.Dlna.csproj @@ -86,6 +86,7 @@ <Compile Include="Profiles\Foobar2000Profile.cs" /> <Compile Include="Profiles\LgTvProfile.cs" /> <Compile Include="Profiles\LinksysDMA2100Profile.cs" /> + <Compile Include="Profiles\MarantzProfile.cs" /> <Compile Include="Profiles\MediaMonkeyProfile.cs" /> <Compile Include="Profiles\PanasonicVieraProfile.cs" /> <Compile Include="Profiles\PopcornHourProfile.cs" /> @@ -177,6 +178,9 @@ <EmbeddedResource Include="Profiles\Xml\Xbox 360.xml" /> <EmbeddedResource Include="Profiles\Xml\Xbox One.xml" /> </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Profiles\Xml\Marantz.xml" /> + </ItemGroup> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index 8c168dc23..15d73e824 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -532,6 +532,7 @@ namespace Emby.Dlna.PlayTo streamInfo.TargetAudioBitrate, streamInfo.TargetAudioSampleRate, streamInfo.TargetAudioChannels, + streamInfo.TargetAudioBitDepth, streamInfo.IsDirectStream, streamInfo.RunTimeTicks, streamInfo.TranscodeSeekInfo); diff --git a/Emby.Dlna/Profiles/DenonAvrProfile.cs b/Emby.Dlna/Profiles/DenonAvrProfile.cs index eed244989..15da48108 100644 --- a/Emby.Dlna/Profiles/DenonAvrProfile.cs +++ b/Emby.Dlna/Profiles/DenonAvrProfile.cs @@ -10,6 +10,8 @@ namespace Emby.Dlna.Profiles { Name = "Denon AVR"; + SupportedMediaTypes = "Audio"; + Identification = new DeviceIdentification { FriendlyName = @"Denon:\[AVR:.*", diff --git a/Emby.Dlna/Profiles/MarantzProfile.cs b/Emby.Dlna/Profiles/MarantzProfile.cs new file mode 100644 index 000000000..0f9f06b88 --- /dev/null +++ b/Emby.Dlna/Profiles/MarantzProfile.cs @@ -0,0 +1,42 @@ +using System.Xml.Serialization; +using MediaBrowser.Model.Dlna; + +namespace Emby.Dlna.Profiles +{ + [XmlRoot("Profile")] + public class MarantzProfile : DefaultProfile + { + public MarantzProfile() + { + Name = "Marantz"; + + SupportedMediaTypes = "Audio"; + + Identification = new DeviceIdentification + { + Manufacturer = @"Marantz", + + Headers = new[] + { + new HttpHeaderInfo + { + Name = "User-Agent", + Value = "Marantz", + Match = HeaderMatchType.Substring + } + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "aac,mp3,wav,wma,flac", + Type = DlnaProfileType.Audio + }, + }; + + ResponseProfiles = new ResponseProfile[] { }; + } + } +} diff --git a/Emby.Dlna/Profiles/MediaMonkeyProfile.cs b/Emby.Dlna/Profiles/MediaMonkeyProfile.cs index dc1c0c237..1ab4bcf82 100644 --- a/Emby.Dlna/Profiles/MediaMonkeyProfile.cs +++ b/Emby.Dlna/Profiles/MediaMonkeyProfile.cs @@ -16,7 +16,7 @@ namespace Emby.Dlna.Profiles { FriendlyName = @"MediaMonkey", - Headers = new[] + Headers = new[] { new HttpHeaderInfo { diff --git a/Emby.Dlna/Profiles/Xml/Denon AVR.xml b/Emby.Dlna/Profiles/Xml/Denon AVR.xml index c1d0a67ea..9c7276f81 100644 --- a/Emby.Dlna/Profiles/Xml/Denon AVR.xml +++ b/Emby.Dlna/Profiles/Xml/Denon AVR.xml @@ -15,7 +15,7 @@ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl> <EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit> <EnableSingleSubtitleLimit>false</EnableSingleSubtitleLimit> - <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes> + <SupportedMediaTypes>Audio</SupportedMediaTypes> <AlbumArtPn>JPEG_SM</AlbumArtPn> <MaxAlbumArtWidth>480</MaxAlbumArtWidth> <MaxAlbumArtHeight>480</MaxAlbumArtHeight> diff --git a/Emby.Dlna/Profiles/Xml/Marantz.xml b/Emby.Dlna/Profiles/Xml/Marantz.xml new file mode 100644 index 000000000..ae843e34a --- /dev/null +++ b/Emby.Dlna/Profiles/Xml/Marantz.xml @@ -0,0 +1,62 @@ +<?xml version="1.0"?> +<Profile xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <Name>Marantz</Name> + <Identification> + <Manufacturer>Marantz</Manufacturer> + <Headers> + <HttpHeaderInfo name="User-Agent" value="Marantz" match="Substring" /> + </Headers> + </Identification> + <Manufacturer>Emby</Manufacturer> + <ManufacturerUrl>http://emby.media/</ManufacturerUrl> + <ModelName>Emby Server</ModelName> + <ModelDescription>Emby</ModelDescription> + <ModelNumber>Emby</ModelNumber> + <ModelUrl>http://emby.media/</ModelUrl> + <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl> + <EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit> + <EnableSingleSubtitleLimit>false</EnableSingleSubtitleLimit> + <SupportedMediaTypes>Audio</SupportedMediaTypes> + <AlbumArtPn>JPEG_SM</AlbumArtPn> + <MaxAlbumArtWidth>480</MaxAlbumArtWidth> + <MaxAlbumArtHeight>480</MaxAlbumArtHeight> + <MaxIconWidth>48</MaxIconWidth> + <MaxIconHeight>48</MaxIconHeight> + <MaxStreamingBitrate>40000000</MaxStreamingBitrate> + <MaxStaticBitrate>40000000</MaxStaticBitrate> + <MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate> + <MaxStaticMusicBitrate xsi:nil="true" /> + <XDlnaDoc>DMS-1.50</XDlnaDoc> + <ProtocolInfo>http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_BASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_FULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-matroska:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_LPCM;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_L6_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_NDSD;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_LPCM_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000</ProtocolInfo> + <TimelineOffsetSeconds>0</TimelineOffsetSeconds> + <RequiresPlainVideoItems>false</RequiresPlainVideoItems> + <RequiresPlainFolders>false</RequiresPlainFolders> + <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar> + <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests> + <XmlRootAttributes /> + <DirectPlayProfiles> + <DirectPlayProfile container="aac,mp3,wav,wma,flac" type="Audio" /> + </DirectPlayProfiles> + <TranscodingProfiles> + <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" minSegments="0" segmentLength="0" breakOnNonKeyFrames="false" /> + <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" minSegments="0" segmentLength="0" breakOnNonKeyFrames="false" /> + <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" minSegments="0" segmentLength="0" breakOnNonKeyFrames="false" /> + </TranscodingProfiles> + <ContainerProfiles /> + <CodecProfiles /> + <ResponseProfiles /> + <SubtitleProfiles> + <SubtitleProfile format="srt" method="External" /> + <SubtitleProfile format="sub" method="External" /> + <SubtitleProfile format="srt" method="Embed" /> + <SubtitleProfile format="ass" method="Embed" /> + <SubtitleProfile format="ssa" method="Embed" /> + <SubtitleProfile format="smi" method="Embed" /> + <SubtitleProfile format="dvdsub" method="Embed" /> + <SubtitleProfile format="pgs" method="Embed" /> + <SubtitleProfile format="pgssub" method="Embed" /> + <SubtitleProfile format="sub" method="Embed" /> + <SubtitleProfile format="subrip" method="Embed" /> + <SubtitleProfile format="vtt" method="Embed" /> + </SubtitleProfiles> +</Profile>
\ No newline at end of file diff --git a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs index d4be2dabe..1a53ad672 100644 --- a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs @@ -2,11 +2,14 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Extensions; using MediaBrowser.Controller.Persistence; namespace Emby.Server.Implementations.Library.Validators @@ -78,6 +81,35 @@ namespace Emby.Server.Implementations.Library.Validators progress.Report(percent); } + names = names.Select(i => i.RemoveDiacritics()).DistinctNames().ToList(); + + var artistEntities = _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(MusicArtist).Name } + + }).Cast<MusicArtist>().ToList(); + + foreach (var artist in artistEntities) + { + if (!artist.IsAccessedByName) + { + continue; + } + + var name = (artist.Name ?? string.Empty).RemoveDiacritics(); + + if (!names.Contains(name, StringComparer.OrdinalIgnoreCase)) + { + _logger.Info("Deleting dead artist {0} {1}.", artist.Id.ToString("N"), artist.Name); + + await _libraryManager.DeleteItem(artist, new DeleteOptions + { + DeleteFileLocation = false + + }).ConfigureAwait(false); + } + } + progress.Report(100); } } diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index e4ef294d1..8d01e4021 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -869,7 +869,7 @@ namespace MediaBrowser.Api.Playback var videoCodec = state.ActualOutputVideoCodec; var mediaProfile = state.VideoRequest == null ? - profile.GetAudioMediaProfile(state.OutputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate, state.OutputAudioSampleRate) : + profile.GetAudioMediaProfile(state.OutputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate, state.OutputAudioSampleRate, state.OutputAudioBitDepth) : profile.GetVideoMediaProfile(state.OutputContainer, audioCodec, videoCodec, @@ -966,6 +966,7 @@ namespace MediaBrowser.Api.Playback state.OutputAudioBitrate, state.OutputAudioSampleRate, state.OutputAudioChannels, + state.OutputAudioBitDepth, isStaticallyStreamed, state.RunTimeTicks, state.TranscodeSeekInfo diff --git a/MediaBrowser.Api/Playback/UniversalAudioService.cs b/MediaBrowser.Api/Playback/UniversalAudioService.cs index b9bcd106e..118bf5246 100644 --- a/MediaBrowser.Api/Playback/UniversalAudioService.cs +++ b/MediaBrowser.Api/Playback/UniversalAudioService.cs @@ -52,6 +52,7 @@ namespace MediaBrowser.Api.Playback public string TranscodingContainer { get; set; } public string TranscodingProtocol { get; set; } public int? MaxAudioSampleRate { get; set; } + public int? MaxAudioBitDepth { get; set; } public bool EnableRedirection { get; set; } public bool EnableRemoteMedia { get; set; } @@ -164,6 +165,18 @@ namespace MediaBrowser.Api.Playback }); } + if (request.MaxAudioBitDepth.HasValue) + { + // codec profile + conditions.Add(new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + IsRequired = false, + Property = ProfileConditionValue.AudioBitDepth, + Value = request.MaxAudioBitDepth.Value.ToString(CultureInfo.InvariantCulture) + }); + } + if (request.MaxAudioChannels.HasValue) { // codec profile @@ -266,6 +279,7 @@ namespace MediaBrowser.Api.Playback Static = isStatic, SegmentContainer = request.TranscodingContainer, AudioSampleRate = request.MaxAudioSampleRate, + MaxAudioBitDepth = request.MaxAudioBitDepth, BreakOnNonKeyFrames = transcodingProfile.BreakOnNonKeyFrames, TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(",", mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray()) }; @@ -310,6 +324,7 @@ namespace MediaBrowser.Api.Playback StartTimeTicks = request.StartTimeTicks, Static = isStatic, AudioSampleRate = request.MaxAudioSampleRate, + MaxAudioBitDepth = request.MaxAudioBitDepth, TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(",", mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray()) }; diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index a83a6a15e..b552579a8 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -284,6 +284,29 @@ namespace MediaBrowser.Controller.MediaEncoding } } + public int? OutputAudioBitDepth + { + get + { + if (BaseRequest.Static || string.Equals(OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase)) + { + if (AudioStream != null) + { + return AudioStream.BitDepth; + } + } + + //else if (BaseRequest.AudioSampleRate.HasValue) + //{ + // // Don't exceed what the encoder supports + // // Seeing issues of attempting to encode to 88200 + // return Math.Min(44100, BaseRequest.AudioSampleRate.Value); + //} + + return null; + } + } + /// <summary> /// Predicts the audio sample rate that will be in the output stream /// </summary> diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs index 28ef66566..5fc93bf38 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs @@ -83,6 +83,8 @@ namespace MediaBrowser.Controller.MediaEncoding [ApiMember(Name = "AudioSampleRate", Description = "Optional. Specify a specific audio sample rate, e.g. 44100", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? AudioSampleRate { get; set; } + public int? MaxAudioBitDepth { get; set; } + /// <summary> /// Gets or sets the audio bit rate. /// </summary> diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index ba5f625f5..50d3d254a 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -262,7 +262,7 @@ namespace MediaBrowser.MediaEncoding.Encoder var outputContainer = state.Options.OutputContainer; var mediaProfile = state.IsVideoRequest ? - profile.GetAudioMediaProfile(outputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate, state.OutputAudioSampleRate) : + profile.GetAudioMediaProfile(outputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate, state.OutputAudioSampleRate, state.OutputAudioBitDepth) : profile.GetVideoMediaProfile(outputContainer, audioCodec, videoCodec, diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs index a388bf98b..291096f75 100644 --- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs +++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Model.Dlna public bool IsVideoConditionSatisfied(ProfileCondition condition, int? width, int? height, - int? bitDepth, + int? videoBitDepth, int? videoBitrate, string videoProfile, double? videoLevel, @@ -46,7 +46,7 @@ namespace MediaBrowser.Model.Dlna case ProfileConditionValue.PacketLength: return IsConditionSatisfied(condition, packetLength); case ProfileConditionValue.VideoBitDepth: - return IsConditionSatisfied(condition, bitDepth); + return IsConditionSatisfied(condition, videoBitDepth); case ProfileConditionValue.VideoBitrate: return IsConditionSatisfied(condition, videoBitrate); case ProfileConditionValue.Height: @@ -79,7 +79,7 @@ namespace MediaBrowser.Model.Dlna } } - public bool IsAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, int? audioSampleRate) + public bool IsAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth) { switch (condition.Property) { @@ -89,6 +89,8 @@ namespace MediaBrowser.Model.Dlna return IsConditionSatisfied(condition, audioChannels); case ProfileConditionValue.AudioSampleRate: return IsConditionSatisfied(condition, audioSampleRate); + case ProfileConditionValue.AudioBitDepth: + return IsConditionSatisfied(condition, audioBitDepth); default: throw new ArgumentException("Unexpected condition on audio file: " + condition.Property); } @@ -97,7 +99,8 @@ namespace MediaBrowser.Model.Dlna public bool IsVideoAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, - int? audioSampleRate, + int? audioSampleRate, + int? audioBitDepth, string audioProfile, bool? isSecondaryTrack) { @@ -113,6 +116,8 @@ namespace MediaBrowser.Model.Dlna return IsConditionSatisfied(condition, isSecondaryTrack); case ProfileConditionValue.AudioSampleRate: return IsConditionSatisfied(condition, audioSampleRate); + case ProfileConditionValue.AudioBitDepth: + return IsConditionSatisfied(condition, audioBitDepth); default: throw new ArgumentException("Unexpected condition on audio file: " + condition.Property); } diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs index 6f6994a7e..8a9dc1dd1 100644 --- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -55,6 +55,7 @@ namespace MediaBrowser.Model.Dlna int? audioBitrate, int? audioSampleRate, int? audioChannels, + int? audioBitDepth, bool isDirectStream, long? runtimeTicks, TranscodeSeekInfo transcodeSeekInfo) @@ -86,7 +87,8 @@ namespace MediaBrowser.Model.Dlna audioCodec, audioChannels, audioBitrate, - audioSampleRate); + audioSampleRate, + audioBitDepth); string orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 33d73e3bb..cd7ff08d6 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -185,7 +185,7 @@ namespace MediaBrowser.Model.Dlna return null; } - public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, int? audioChannels, int? audioBitrate, int? audioSampleRate) + public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth) { container = StringHelper.TrimStart(container ?? string.Empty, '.'); @@ -213,7 +213,7 @@ namespace MediaBrowser.Model.Dlna var anyOff = false; foreach (ProfileCondition c in i.Conditions) { - if (!conditionProcessor.IsAudioConditionSatisfied(GetModelProfileCondition(c), audioChannels, audioBitrate, audioSampleRate)) + if (!conditionProcessor.IsAudioConditionSatisfied(GetModelProfileCondition(c), audioChannels, audioBitrate, audioSampleRate, audioBitDepth)) { anyOff = true; break; diff --git a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs index 208a7df7e..a96e9ac36 100644 --- a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs +++ b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs @@ -23,6 +23,7 @@ VideoCodecTag = 19, IsAvc = 20, IsInterlaced = 21, - AudioSampleRate = 22 + AudioSampleRate = 22, + AudioBitDepth = 23 } }
\ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index ebfeb358e..342796a10 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -167,6 +167,9 @@ namespace MediaBrowser.Model.Dlna case ProfileConditionValue.VideoBitDepth: return TranscodeReason.VideoBitDepthNotSupported; + case ProfileConditionValue.AudioBitDepth: + return TranscodeReason.AudioBitDepthNotSupported; + case ProfileConditionValue.VideoBitrate: return TranscodeReason.VideoBitrateNotSupported; @@ -234,6 +237,7 @@ namespace MediaBrowser.Model.Dlna int? inputAudioChannels = audioStream == null ? null : audioStream.Channels; int? inputAudioBitrate = audioStream == null ? null : audioStream.BitDepth; int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate; + int? inputAudioBitDepth = audioStream == null ? null : audioStream.BitDepth; if (directPlayMethods.Count > 0) { @@ -250,7 +254,7 @@ namespace MediaBrowser.Model.Dlna bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) { - if (!conditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate)) + if (!conditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth)) { LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item); applyConditions = false; @@ -271,7 +275,7 @@ namespace MediaBrowser.Model.Dlna bool all = true; foreach (ProfileCondition c in conditions) { - if (!conditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate)) + if (!conditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth)) { LogConditionFailure(options.Profile, "AudioCodecProfile", c, item); var transcodeReason = GetTranscodeReasonForFailedCondition(c); @@ -351,7 +355,7 @@ namespace MediaBrowser.Model.Dlna bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) { - if (!conditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate)) + if (!conditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth)) { LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item); applyConditions = false; @@ -734,8 +738,9 @@ namespace MediaBrowser.Model.Dlna int? audioChannels = audioStream == null ? null : audioStream.Channels; string audioProfile = audioStream == null ? null : audioStream.Profile; int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate; + int? inputAudioBitDepth = audioStream == null ? null : audioStream.BitDepth; - if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, audioProfile, isSecondaryAudio)) + if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth, audioProfile, isSecondaryAudio)) { LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item); applyConditions = false; @@ -972,6 +977,7 @@ namespace MediaBrowser.Model.Dlna int? audioChannels = audioStream == null ? null : audioStream.Channels; string audioProfile = audioStream == null ? null : audioStream.Profile; int? audioSampleRate = audioStream == null ? null : audioStream.SampleRate; + int? audioBitDepth = audioStream == null ? null : audioStream.BitDepth; TransportStreamTimestamp? timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp; int? packetLength = videoStream == null ? null : videoStream.PacketLength; @@ -1066,7 +1072,7 @@ namespace MediaBrowser.Model.Dlna bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) { - if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, audioBitrate, audioSampleRate, audioProfile, isSecondaryAudio)) + if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio)) { LogConditionFailure(profile, "VideoAudioCodecProfile", applyCondition, mediaSource); applyConditions = false; @@ -1086,7 +1092,7 @@ namespace MediaBrowser.Model.Dlna foreach (ProfileCondition i in conditions) { - if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioSampleRate, audioProfile, isSecondaryAudio)) + if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio)) { LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource); diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index d70d89cf7..9c8e8b030 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -480,6 +480,18 @@ namespace MediaBrowser.Model.Dlna /// <summary> /// Predicts the audio sample rate that will be in the output stream /// </summary> + public int? TargetAudioBitDepth + { + get + { + MediaStream stream = TargetAudioStream; + return stream == null ? null : stream.BitDepth; + } + } + + /// <summary> + /// Predicts the audio sample rate that will be in the output stream + /// </summary> public int? TargetVideoBitDepth { get diff --git a/MediaBrowser.Model/Session/TranscodingInfo.cs b/MediaBrowser.Model/Session/TranscodingInfo.cs index 67eac6fd5..f1cbacd90 100644 --- a/MediaBrowser.Model/Session/TranscodingInfo.cs +++ b/MediaBrowser.Model/Session/TranscodingInfo.cs @@ -47,6 +47,7 @@ namespace MediaBrowser.Model.Session VideoBitrateNotSupported = 16, VideoFramerateNotSupported = 17, VideoLevelNotSupported = 18, - VideoProfileNotSupported = 19 + VideoProfileNotSupported = 19, + AudioBitDepthNotSupported = 20 } }
\ No newline at end of file diff --git a/SharedVersion.cs b/SharedVersion.cs index d6bc167e6..54c495e32 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.20.13")] +[assembly: AssemblyVersion("3.2.20.14")] |
