public static MediaItem CreateMediaItem(string filename) { IMediaAccessor mediaAccessor = ServiceRegistration.Get <IMediaAccessor>(); IEnumerable <Guid> meIds = mediaAccessor.GetMetadataExtractorsForMIATypes(NECESSARY_VIDEO_MIAS); ResourceLocator resourceLocator = new ResourceLocator(LocalFsResourceProviderBase.ToResourcePath(filename)); IResourceAccessor ra = resourceLocator.CreateAccessor(); if (ra == null) { return(null); } using (ra) return(mediaAccessor.CreateLocalMediaItem(ra, meIds)); }
protected virtual async Task <bool> SaveSubtitleAsync(SubtitleInfo subtitle, IDictionary <BaseSubtitleMatch <TId>, byte[]> downloads, bool overwriteExisting) { var mediaFile = subtitle.MediaFiles.First(); var namingTemplate = ResourcePath.GetFileNameWithoutExtension(mediaFile.NativeResourcePath.FileName); var templatePartMatch = _regexMultiPartVideo.Match(namingTemplate); foreach (var subtitleMatch in downloads.Keys) { var subPartMatch = _regexMultiPartVideo.Match(subtitleMatch.ItemName); string subName = namingTemplate; if (subPartMatch.Success && templatePartMatch.Success) { if (!int.TryParse(templatePartMatch.Groups["disc"].Value, out var _) || !int.TryParse(subPartMatch.Groups["disc"].Value, out var partNum)) { continue; } subName = _regexMultiPartVideo.Replace(namingTemplate, "${1}${2}${4}" + partNum + "${3}"); } string lang = new CultureInfo(subtitleMatch.Language).EnglishName; var dir = ResourcePathHelper.GetDirectoryName(mediaFile.NativeResourcePath.Serialize()); var sub = $"{subName}.{lang}{Path.GetExtension(subtitleMatch.ItemName)}"; ResourcePath subtitlePath = ResourcePath.Deserialize(dir); //File based access var resLoc = new ResourceLocator(mediaFile.NativeSystemId, subtitlePath); using (IResourceAccessor mediaItemAccessor = resLoc.CreateAccessor()) using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor)) using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess()) { using (var stream = rah.LocalFsResourceAccessor.CreateOpenWrite(sub, overwriteExisting)) { var bytes = downloads[subtitleMatch]; if (stream != null) { await stream.WriteAsync(bytes, 0, bytes.Length); } } } } return(true); }
public override async Task <AsyncResult <ContentDirectoryMessaging.MediaItemChangeType> > ProcessAsync(MediaItem mediaItem) { IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory; bool removeFromML = IsManagedByMediaLibrary(mediaItem) && cd != null; var falseResult = new AsyncResult <ContentDirectoryMessaging.MediaItemChangeType>(false, ContentDirectoryMessaging.MediaItemChangeType.None); // Support multi-resource media items and secondary resources IList <MultipleMediaItemAspect> providerAspects; if (!MediaItemAspect.TryGetAspects(mediaItem.Aspects, ProviderResourceAspect.Metadata, out providerAspects)) { return(falseResult); } foreach (MultipleMediaItemAspect providerAspect in providerAspects) { string systemId = (string)providerAspect[ProviderResourceAspect.ATTR_SYSTEM_ID]; string resourceAccessorPath = (string)providerAspect[ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH]; var rl = new ResourceLocator(systemId, ResourcePath.Deserialize(resourceAccessorPath)); using (var ra = rl.CreateAccessor()) { var rad = ra as IResourceDeletor; if (rad == null) { return(falseResult); } // First try to delete the file from storage. if (!rad.Delete()) { return(falseResult); } // If the MediaItem was loaded from ML, remove it there as well. if (removeFromML) { await cd.DeleteMediaItemOrPathAsync(rl.NativeSystemId, rl.NativeResourcePath, true); } } } // Check for special cases here: // 1) Recordings have an additional .xml attached // 2) Deleting files could lead to empty folders that should be also removed foreach (DeleteRule rule in _defaultRules.Where(r => r.IsEnabled)) { if (mediaItem.Aspects.ContainsKey(rule.HasAspectGuid)) { var tsPath = mediaItem.GetResourceLocator().NativeResourcePath.ToString(); foreach (string otherExtension in rule.DeleteOtherExtensions) { string otherFilePath = ProviderPathHelper.ChangeExtension(tsPath, otherExtension); IResourceAccessor ra; if (!ResourcePath.Deserialize(otherFilePath).TryCreateLocalResourceAccessor(out ra)) { continue; } // Delete other file. We do not check here for existance of file, the Delete needs to handle this. using (ra) { var rad = ra as IResourceDeletor; rad?.Delete(); } } if (rule.DeleteEmptyFolders) { var folderPath = ProviderPathHelper.GetDirectoryName(tsPath); IResourceAccessor ra; if (!ResourcePath.Deserialize(folderPath).TryCreateLocalResourceAccessor(out ra)) { continue; } // Delete folder if empty using (ra) { IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra != null) { var isEmpty = fsra.GetFiles().Count == 0 && fsra.GetChildDirectories().Count == 0; if (isEmpty) { var rad = ra as IResourceDeletor; rad?.Delete(); } } } } } } return(new AsyncResult <ContentDirectoryMessaging.MediaItemChangeType>(true, ContentDirectoryMessaging.MediaItemChangeType.Deleted)); }