async Task <List <DbMediaFile> > IndexSongsAsync( MediaMetadata[] songItems, Dictionary <string, DbArtist> artistsCache, Dictionary <string, DbAlbum> albumsCache) { var songsDelta = new List <DbMediaFile>(); foreach (var s in songItems) { var e = DbMediaFile.FromMediaInfo(s.Item1, s.Item3); e.Path = s.Item2; // Empty AlbumArtist: Use the most frequently artist in album instead if (string.IsNullOrEmpty(e.AlbumArtist)) { if (albumsCache.ContainsKey(e.Album)) { e.AlbumArtist = albumsCache[e.Album].Artist; } } e.RelatedAlbumId = albumsCache.ContainsKey(e.Album) ? albumsCache[e.Album].Id : (int?)null; // Here, the relationship is song -> album's artist. (Same behavior as Groove) e.RelatedArtistId = artistsCache.ContainsKey(e.AlbumArtist) ? artistsCache[e.AlbumArtist].Id : (int?)null; m_dbContext.MediaFiles.Add(e); songsDelta.Add(e); } await m_dbContext.SaveChangesAsync(); return(songsDelta); }
public static async Task HandleM3uAsync(StorageFile file, List <MusicPlaybackItem> add) { try { using (var stream = await file.OpenStreamForReadAsync()) using (var sr = new StreamReader(stream)) { var musicItems = M3u.Parse(sr.Lines()); foreach (var music in musicItems) { try { var f = await NativeMethods.GetStorageFileFromPathAsync(music); if (f == null) { continue; } IMediaInfo info = null; using (var s = await f.OpenAsync(FileAccessMode.Read)) { NativeMethods.GetMediaInfoFromStream(s, out info); } if (info == null) { continue; } var prop = await file.GetBasicPropertiesAsync(); var internalEntity = DbMediaFile.FromMediaInfo(info, prop.DateModified); internalEntity.IsExternal = true; internalEntity.Path = f.Path; internalEntity.Id = -65535; if (string.IsNullOrWhiteSpace(internalEntity.Title) && !string.IsNullOrWhiteSpace(internalEntity.Path)) { internalEntity.Title = Path.GetFileNameWithoutExtension(internalEntity.Path); } add.Add(MusicPlaybackItem.CreateFromMediaFile(internalEntity)); } catch { } } } } catch { } }
public static async Task HandleWplAsync(StorageFile file, List <MusicPlaybackItem> addItem) { try { if (!ApiInformation.IsApiContractPresent("Windows.Media.Playlists.PlaylistsContract", 1)) { //TODO: Tell user the platform is not supported. return; } var playlist = await Windows.Media.Playlists.Playlist.LoadAsync(file); foreach (var item in playlist.Files) { IMediaInfo info = null; using (var stream = await item.OpenAsync(FileAccessMode.Read)) { NativeMethods.GetMediaInfoFromStream(stream, out info); } if (info == null) { continue; } var prop = await item.GetBasicPropertiesAsync(); var internalEntity = DbMediaFile.FromMediaInfo(info, prop.DateModified); internalEntity.IsExternal = true; internalEntity.Path = item.Path; internalEntity.Id = -65535; if (string.IsNullOrWhiteSpace(internalEntity.Title) && !string.IsNullOrWhiteSpace(internalEntity.Path)) { internalEntity.Title = Path.GetFileNameWithoutExtension(internalEntity.Path); } addItem.Add(MusicPlaybackItem.CreateFromMediaFile(internalEntity)); } } catch { } }
public static async Task <IEnumerable <MusicPlaybackItem> > HandleFileWithCue(StorageFile file, CueFile cue) { //Cue files will only have track number var items = cue.Indices .OrderBy(c => ParseWithDefaultFallback( c.TrackInfo.TrackNumber)); List <MusicPlaybackItem> files = new List <MusicPlaybackItem>(); IMediaInfo info = null; using (var stream = await file.OpenAsync(FileAccessMode.Read)) { NativeMethods.GetMediaInfoFromStream( stream, out info); } if (info == null) { return(files); } var prop = await file.GetBasicPropertiesAsync(); foreach (ManagedAudioIndexCue item in items) { if (item.TrackInfo.Duration == TimeSpan.Zero) { (item.TrackInfo as CueMediaInfo).Duration = item.Duration = info.Duration - item.StartTime; } var internalEntity = DbMediaFile.FromMediaInfo(item.TrackInfo, prop.DateModified); internalEntity.IsExternal = true; internalEntity.StartTime = (int)item.StartTime.TotalMilliseconds; internalEntity.Path = file.Path; internalEntity.Id = -65535; files.Add(MusicPlaybackItem.CreateFromMediaFile(internalEntity)); } return(files); }
public static async Task <List <MusicPlaybackItem> > GetPlaybackItemsFromFilesAsync(IReadOnlyList <IStorageItem> items) { var files = new List <StorageFile>(); var added = new List <MusicPlaybackItem>(); // [| (cue file, full file path of missing file) |] var failedCue = new List <Tuple <StorageFile, string> >(); foreach (var file in await GetAllFiles(items)) { files.Add(file); } var listFiles = PickAndRemoveCueM3uWplFiles(files); foreach (var cueFile in listFiles.Item1) { try { var failedFileName = await HandleCueFileOpen(cueFile, files, added); if (failedFileName != null) { failedCue.Add(new Tuple <StorageFile, string>(cueFile, failedFileName)); } } catch { } } foreach (var m3uFile in listFiles.Item2) { await HandleM3uAsync(m3uFile, added); } foreach (var wplFile in listFiles.Item3) { await HandleWplAsync(wplFile, added); } foreach (var file in files) { try { IMediaInfo info = null; using (var stream = await file.OpenAsync(FileAccessMode.Read)) { NativeMethods.GetMediaInfoFromStream(stream, out info); } if (info == null) { continue; } var cue = info.AllProperties["cuesheet"]; if (!string.IsNullOrWhiteSpace(cue)) { var cueItems = await HandleFileWithCue(file, CueFile.CreateFromString(cue)); added.AddRange(cueItems); continue; } var prop = await file.GetBasicPropertiesAsync(); var internalEntity = DbMediaFile.FromMediaInfo(info, prop.DateModified); internalEntity.IsExternal = true; internalEntity.Path = file.Path; internalEntity.Id = -65535; if (string.IsNullOrWhiteSpace(internalEntity.Title) && !string.IsNullOrWhiteSpace(internalEntity.Path)) { internalEntity.Title = Path.GetFileNameWithoutExtension(internalEntity.Path); } added.Add(MusicPlaybackItem.CreateFromMediaFile(internalEntity)); } catch { } } if (failedCue.Count > 0) { added.AddRange( await FileOpenFailure.AddFailedFilePath( failedCue)); } return(added); }