コード例 #1
0
        public ICollection <Share> CreateDefaultShares()
        {
            List <Share> result = new List <Share>();
            Guid         localFsResourceProviderId = LocalFsResourceProviderBase.LOCAL_FS_RESOURCE_PROVIDER_ID;

            if (LocalResourceProviders.ContainsKey(localFsResourceProviderId))
            {
                string folderPath;
                if (WindowsAPI.GetSpecialFolder(WindowsAPI.SpecialFolder.MyMusic, out folderPath))
                {
                    folderPath = LocalFsResourceProviderBase.ToProviderPath(folderPath);
                    string[] mediaCategories = new[] { DefaultMediaCategories.Audio.ToString() };
                    Share    sd = Share.CreateNewLocalShare(ResourcePath.BuildBaseProviderPath(localFsResourceProviderId, folderPath),
                                                            MY_MUSIC_SHARE_NAME_RESOURE, mediaCategories);
                    result.Add(sd);
                }

                if (WindowsAPI.GetSpecialFolder(WindowsAPI.SpecialFolder.MyVideos, out folderPath))
                {
                    folderPath = LocalFsResourceProviderBase.ToProviderPath(folderPath);
                    string[] mediaCategories = new[] { DefaultMediaCategories.Video.ToString() };
                    Share    sd = Share.CreateNewLocalShare(ResourcePath.BuildBaseProviderPath(localFsResourceProviderId, folderPath),
                                                            MY_VIDEOS_SHARE_NAME_RESOURCE, mediaCategories);
                    result.Add(sd);
                }

                if (WindowsAPI.GetSpecialFolder(WindowsAPI.SpecialFolder.MyPictures, out folderPath))
                {
                    folderPath = LocalFsResourceProviderBase.ToProviderPath(folderPath);
                    string[] mediaCategories = new[] { DefaultMediaCategories.Image.ToString() };
                    Share    sd = Share.CreateNewLocalShare(ResourcePath.BuildBaseProviderPath(localFsResourceProviderId, folderPath),
                                                            MY_PICTURES_SHARE_NAME_RESOURCE, mediaCategories);
                    result.Add(sd);
                }
            }
            if (result.Count > 0)
            {
                return(result);
            }
            // Fallback: If no share was added for the defaults above, use the provider's root folders
            result.AddRange(LocalBaseResourceProviders.Select(resourceProvider => resourceProvider.Metadata).Select(
                                metadata => Share.CreateNewLocalShare(ResourcePath.BuildBaseProviderPath(metadata.ResourceProviderId, "/"), metadata.Name, null)));
            return(result);
        }
コード例 #2
0
        /// <summary>
        /// Helper method to create a valid <see cref="ResourcePath"/> from the given path. This method supports both local and UNC paths and will use the right ResourceProviderId.
        /// </summary>
        /// <param name="path">Path or file name</param>
        /// <returns></returns>
        protected static ResourcePath BuildResourcePath(string path)
        {
            Guid providerId;

            if (path.StartsWith("\\\\"))
            {
                // NetworkNeighborhoodResourceProvider
                providerId = new Guid("{03DD2DA6-4DA8-4D3E-9E55-80E3165729A3}");
                // Cut-off the first \
                path = path.Substring(1);
            }
            else
            {
                providerId = LocalFsResourceProviderBase.LOCAL_FS_RESOURCE_PROVIDER_ID;
            }

            string folderPath   = LocalFsResourceProviderBase.ToProviderPath(path);
            var    resourcePath = ResourcePath.BuildBaseProviderPath(providerId, folderPath);

            return(resourcePath);
        }
コード例 #3
0
        public ICollection <Share> CreateDefaultShares()
        {
            List <Share> result = new List <Share>();
            Guid         localFsResourceProviderId = LocalFsResourceProviderBase.LOCAL_FS_RESOURCE_PROVIDER_ID;

            if (LocalResourceProviders.ContainsKey(localFsResourceProviderId))
            {
                string folderPath;
                if (WindowsAPI.GetSpecialFolder(Environment.SpecialFolder.MyMusic, out folderPath))
                {
                    folderPath = LocalFsResourceProviderBase.ToProviderPath(folderPath);
                    string[] mediaCategories = new[] { DefaultMediaCategories.Audio.ToString() };
                    Share    sd = Share.CreateNewLocalShare(ResourcePath.BuildBaseProviderPath(localFsResourceProviderId, folderPath),
                                                            MY_MUSIC_SHARE_NAME_RESOURE, true, mediaCategories);
                    result.Add(sd);
                }

                if (WindowsAPI.GetSpecialFolder(Environment.SpecialFolder.MyVideos, out folderPath))
                {
                    folderPath = LocalFsResourceProviderBase.ToProviderPath(folderPath);
                    string[] mediaCategories = new[] { DefaultMediaCategories.Video.ToString() };
                    Share    sd = Share.CreateNewLocalShare(ResourcePath.BuildBaseProviderPath(localFsResourceProviderId, folderPath),
                                                            MY_VIDEOS_SHARE_NAME_RESOURCE, true, mediaCategories);
                    result.Add(sd);
                }

                if (WindowsAPI.GetSpecialFolder(Environment.SpecialFolder.MyPictures, out folderPath))
                {
                    folderPath = LocalFsResourceProviderBase.ToProviderPath(folderPath);
                    string[] mediaCategories = new[] { DefaultMediaCategories.Image.ToString() };
                    Share    sd = Share.CreateNewLocalShare(ResourcePath.BuildBaseProviderPath(localFsResourceProviderId, folderPath),
                                                            MY_PICTURES_SHARE_NAME_RESOURCE, true, mediaCategories);
                    result.Add(sd);
                }
            }
            return(result);
        }
コード例 #4
0
        public ResourcePath ExpandResourcePathFromString(string pathStr)
        {
            if (string.IsNullOrEmpty(pathStr))
            {
                return(null);
            }
            // The input string is given by the user. We can cope with three formats:
            // 1) A resource provider path which can be interpreted by the choosen resource provider itself (i.e. a path without the
            //    starting resource provider GUID)
            // 2) A resource path in the resource path syntax (i.e. {[Base-Provider-Id]}://[Base-Provider-Path])
            // 3) A dos path
            if (IsResource(pathStr))
            {
                return(new ResourcePath(new ProviderPathSegment[]
                {
                    new ProviderPathSegment(_metadata.ResourceProviderId, pathStr, true),
                }));
            }
            string providerPath = LocalFsResourceProviderBase.ToProviderPath(pathStr);

            if (IsResource(providerPath))
            {
                return(new ResourcePath(new ProviderPathSegment[]
                {
                    new ProviderPathSegment(_metadata.ResourceProviderId, providerPath, true),
                }));
            }
            try
            {
                return(ResourcePath.Deserialize(pathStr));
            }
            catch (ArgumentException)
            {
                return(null);
            }
        }
コード例 #5
0
        protected int FindExternalSubtitles(ILocalFsResourceAccessor lfsra, IDictionary <Guid, IList <MediaItemAspect> > extractedAspectData)
        {
            int subtitleCount = 0;

            try
            {
                IList <MultipleMediaItemAspect> providerResourceAspects;
                if (!MediaItemAspect.TryGetAspects(extractedAspectData, ProviderResourceAspect.Metadata, out providerResourceAspects))
                {
                    return(0);
                }

                int newResourceIndex = -1;
                foreach (MultipleMediaItemAspect providerResourceAspect in providerResourceAspects)
                {
                    int resouceIndex = providerResourceAspect.GetAttributeValue <int>(ProviderResourceAspect.ATTR_RESOURCE_INDEX);
                    if (newResourceIndex < resouceIndex)
                    {
                        newResourceIndex = resouceIndex;
                    }
                }
                newResourceIndex++;

                using (lfsra.EnsureLocalFileSystemAccess())
                {
                    foreach (MultipleMediaItemAspect mmia in providerResourceAspects)
                    {
                        string       accessorPath = (string)mmia.GetAttributeValue(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH);
                        ResourcePath resourcePath = ResourcePath.Deserialize(accessorPath);

                        if (mmia.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) != ProviderResourceAspect.TYPE_PRIMARY)
                        {
                            continue;
                        }

                        string filePath = LocalFsResourceProviderBase.ToDosPath(resourcePath);
                        if (string.IsNullOrEmpty(filePath))
                        {
                            continue;
                        }

                        List <string> subs = new List <string>();
                        int           videoResouceIndex = (int)mmia.GetAttributeValue(ProviderResourceAspect.ATTR_RESOURCE_INDEX);
                        string[]      subFiles          = Directory.GetFiles(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + "*.*");
                        if (subFiles != null)
                        {
                            subs.AddRange(subFiles);
                        }
                        foreach (string folder in SUBTITLE_FOLDERS)
                        {
                            if (string.IsNullOrEmpty(Path.GetPathRoot(folder)) && Directory.Exists(Path.Combine(Path.GetDirectoryName(filePath), folder))) //Is relative path
                            {
                                subFiles = Directory.GetFiles(Path.Combine(Path.GetDirectoryName(filePath), folder), Path.GetFileNameWithoutExtension(filePath) + "*.*");
                            }
                            else if (Directory.Exists(folder)) //Is absolute path
                            {
                                subFiles = Directory.GetFiles(folder, Path.GetFileNameWithoutExtension(filePath) + "*.*");
                            }

                            if (subFiles != null)
                            {
                                subs.AddRange(subFiles);
                            }
                        }
                        foreach (string subFile in subFiles)
                        {
                            if (!HasSubtitleExtension(subFile))
                            {
                                continue;
                            }

                            LocalFsResourceAccessor fsra = new LocalFsResourceAccessor((LocalFsResourceProvider)lfsra.ParentProvider, LocalFsResourceProviderBase.ToProviderPath(subFile));

                            //Check if already exists
                            bool exists = false;
                            foreach (MultipleMediaItemAspect providerResourceAspect in providerResourceAspects)
                            {
                                string       subAccessorPath = (string)providerResourceAspect.GetAttributeValue(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH);
                                ResourcePath subResourcePath = ResourcePath.Deserialize(subAccessorPath);
                                if (subResourcePath.Equals(fsra.CanonicalLocalResourcePath))
                                {
                                    //Already exists
                                    exists = true;
                                    break;
                                }
                            }
                            if (exists)
                            {
                                continue;
                            }

                            string subFormat = GetSubtitleFormat(subFile);
                            if (!string.IsNullOrEmpty(subFormat))
                            {
                                MultipleMediaItemAspect providerResourceAspect = MediaItemAspect.CreateAspect(extractedAspectData, ProviderResourceAspect.Metadata);
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_INDEX, newResourceIndex);
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_TYPE, ProviderResourceAspect.TYPE_SECONDARY);
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, GetSubtitleMime(subFormat));
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_SIZE, fsra.Size);
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH, fsra.CanonicalLocalResourcePath.Serialize());

                                MultipleMediaItemAspect subtitleResourceAspect = MediaItemAspect.CreateAspect(extractedAspectData, SubtitleAspect.Metadata);
                                subtitleResourceAspect.SetAttribute(SubtitleAspect.ATTR_RESOURCE_INDEX, newResourceIndex);
                                subtitleResourceAspect.SetAttribute(SubtitleAspect.ATTR_VIDEO_RESOURCE_INDEX, videoResouceIndex);
                                subtitleResourceAspect.SetAttribute(SubtitleAspect.ATTR_STREAM_INDEX, -1); //External subtitle
                                subtitleResourceAspect.SetAttribute(SubtitleAspect.ATTR_SUBTITLE_FORMAT, subFormat);
                                subtitleResourceAspect.SetAttribute(SubtitleAspect.ATTR_INTERNAL, false);
                                subtitleResourceAspect.SetAttribute(SubtitleAspect.ATTR_DEFAULT, subFile.ToLowerInvariant().Contains(".default."));
                                subtitleResourceAspect.SetAttribute(SubtitleAspect.ATTR_FORCED, subFile.ToLowerInvariant().Contains(".forced."));

                                bool   imageBased = IsImageBasedSubtitle(subFormat);
                                string language   = GetSubtitleLanguage(subFile, imageBased);
                                if (language != null)
                                {
                                    subtitleResourceAspect.SetAttribute(SubtitleAspect.ATTR_SUBTITLE_LANGUAGE, language);
                                }
                                if (imageBased == false)
                                {
                                    string encoding = GetSubtitleEncoding(subFile, language);
                                    if (encoding != null)
                                    {
                                        subtitleResourceAspect.SetAttribute(SubtitleAspect.ATTR_SUBTITLE_ENCODING, encoding);
                                    }
                                }
                                else
                                {
                                    subtitleResourceAspect.SetAttribute(SubtitleAspect.ATTR_SUBTITLE_ENCODING, SubtitleAspect.BINARY_ENCODING);
                                }
                                newResourceIndex++;
                                subtitleCount++;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                ServiceRegistration.Get <ILogger>().Info("SubtitleMetadataExtractor: Exception finding external subtitles for resource '{0}' (Text: '{1}')", e, lfsra.CanonicalLocalResourcePath, e.Message);
            }
            return(subtitleCount);
        }
コード例 #6
0
        protected void PrepareMediaSources()
        {
            Dictionary <string, ICollection <MediaCategory> > checkFolders = new Dictionary <string, ICollection <MediaCategory> >();
            List <string> recordingFolders;
            string        singlePattern;
            string        seriesPattern;

            if (!GetRecordingConfiguration(out recordingFolders, out singlePattern, out seriesPattern))
            {
                ServiceRegistration.Get <ILogger>().Warn("SlimTvService: Unable to configure MediaSource for recordings, probably TV configuration wasn't run yet.");
                return;
            }

            string movieSubfolder  = GetFixedFolderPart(singlePattern);
            string seriesSubfolder = GetFixedFolderPart(seriesPattern);

            foreach (var recordingFolder in recordingFolders)
            {
                if (!string.IsNullOrEmpty(movieSubfolder) && !string.IsNullOrEmpty(seriesSubfolder))
                {
                    // If there are different target folders defined, register the media sources with specialized Series/Movie types
                    checkFolders.Add(FileUtils.CheckTrailingPathDelimiter(Path.Combine(recordingFolder, movieSubfolder)), new HashSet <MediaCategory> {
                        DefaultMediaCategories.Video, Movie
                    });
                    checkFolders.Add(FileUtils.CheckTrailingPathDelimiter(Path.Combine(recordingFolder, seriesSubfolder)), new HashSet <MediaCategory> {
                        DefaultMediaCategories.Video, Series
                    });
                }
                else
                {
                    checkFolders.Add(FileUtils.CheckTrailingPathDelimiter(recordingFolder), new HashSet <MediaCategory> {
                        DefaultMediaCategories.Video
                    });
                }
            }

            IMediaLibrary mediaLibrary = ServiceRegistration.Get <IMediaLibrary>();
            int           cnt          = 1;

            foreach (var folderTypes in checkFolders)
            {
                try
                {
                    List <Share> shares;
                    // Check if there are already share(s) for the folder
                    if (GetSharesForPath(folderTypes.Key, out shares))
                    {
                        continue;
                    }

                    var   folderPath      = LocalFsResourceProviderBase.ToProviderPath(folderTypes.Key);
                    var   mediaCategories = folderTypes.Value.Select(mc => mc.CategoryName);
                    Share sd = Share.CreateNewLocalShare(ResourcePath.BuildBaseProviderPath(LocalFsResourceProviderBase.LOCAL_FS_RESOURCE_PROVIDER_ID, folderPath),
                                                         string.Format("Recordings ({0})", cnt), mediaCategories);

                    mediaLibrary.RegisterShare(sd);
                    cnt++;
                }
                catch (Exception ex)
                {
                    ServiceRegistration.Get <ILogger>().Error("SlimTvService: Error registering new MediaSource.", ex);
                }
            }
        }
コード例 #7
0
        protected override async Task <bool> ConvertSubtitleFileAsync(string clientId, VideoTranscoding video, double timeStart, string transcodingFile, SubtitleStream sourceSubtitle, SubtitleStream res)
        {
            SubtitleCodec targetCodec = video.TargetSubtitleCodec;

            if (targetCodec == SubtitleCodec.Unknown)
            {
                targetCodec = sourceSubtitle.Codec;
            }

            string tempFile          = null;
            FFMpegTranscodeData data = new FFMpegTranscodeData(_cachePath)
            {
                TranscodeId = video.TranscodeId + "_sub", ClientId = clientId
            };

            if (string.IsNullOrEmpty(video.TranscoderBinPath) == false)
            {
                data.TranscoderBinPath = video.TranscoderBinPath;
            }
            if (string.IsNullOrEmpty(video.TranscoderArguments) == false)
            {
                // TODO: not sure if this is working
                data.TranscoderArguments = video.TranscoderArguments;
                data.InputMediaFilePaths.Add(0, res.SourcePath);
                data.InputArguments.Add(0, new List <string>());
            }
            else
            {
                tempFile = transcodingFile + ".tmp";
                res      = await ConvertSubtitleEncodingAsync(res, tempFile, video.TargetSubtitleCharacterEncoding).ConfigureAwait(false);

                // TODO: not sure if this is working
                _ffMpegCommandline.InitTranscodingParameters(false, new Dictionary <int, string> {
                    { 0, res.SourcePath }
                }, ref data);
                data.InputArguments[0].Add(string.Format("-f {0}", FFMpegGetSubtitleContainer.GetSubtitleContainer(sourceSubtitle.Codec)));
                if (timeStart > 0)
                {
                    data.OutputArguments.Add(string.Format(CultureInfo.InvariantCulture, "-ss {0:0.0}", timeStart));
                }

                res.Codec = targetCodec;
                string subtitleEncoder = "copy";
                if (res.Codec == SubtitleCodec.Unknown)
                {
                    res.Codec = SubtitleCodec.Ass;
                }

                if (sourceSubtitle.Codec != res.Codec)
                {
                    subtitleEncoder = FFMpegGetSubtitleContainer.GetSubtitleContainer(res.Codec);
                }

                string subtitleFormat = FFMpegGetSubtitleContainer.GetSubtitleContainer(res.Codec);
                data.OutputArguments.Add("-vn");
                data.OutputArguments.Add("-an");
                data.OutputArguments.Add(string.Format("-c:s {0}", subtitleEncoder));
                data.OutputArguments.Add(string.Format("-f {0}", subtitleFormat));
            }
            data.OutputFilePath = transcodingFile;

            _logger.Debug("FFMpegMediaConverter: Invoking transcoder to transcode subtitle file '{0}' for transcode '{1}'", res.SourcePath, data.TranscodeId);
            bool success = false;
            var  path    = ResourcePath.Deserialize(res.SourcePath);

            if (path.TryCreateLocalResourceAccessor(out var subRes))
            {
                using (var rah = new LocalFsResourceAccessorHelper(subRes))
                    using (var access = rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess())
                    {
                        var result = await FFMpegBinary.FFMpegExecuteWithResourceAccessAsync(rah.LocalFsResourceAccessor, data.TranscoderArguments, ProcessPriorityClass.Normal, _transcoderTimeout).ConfigureAwait(false);

                        success = result.Success;
                    }
            }
            if (success && File.Exists(transcodingFile) == true)
            {
                if (tempFile != null && File.Exists(tempFile))
                {
                    File.Delete(tempFile);
                }
                res.SourcePath = LocalFsResourceProviderBase.ToProviderPath(transcodingFile);
                return(true);
            }
            return(false);
        }