public static void UpdateMainTileForPlayback(DbMediaFile item, string imageUrl) { lock (_lock) { // Not supported on IoT and Holographic platform. if (PlatformInfo.CurrentPlatform != Platform.WindowsMobile && PlatformInfo.CurrentPlatform != Platform.WindowsDesktop) { return; } // Large tile var largeTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare310x310ImageAndTextOverlay02); var largeTileTextAttributes = largeTileXml.GetElementsByTagName("text"); largeTileTextAttributes[0].InnerText = item.Title; largeTileTextAttributes[1].InnerText = $"{item.Album} by {item.Artist}"; var largeTileImageAttributes = largeTileXml.GetElementsByTagName("image"); ((XmlElement)largeTileImageAttributes[0]).SetAttribute("src", string.IsNullOrEmpty(imageUrl) ? CommonSharedStrings.DefaultAlbumImagePath : imageUrl); ((XmlElement)largeTileImageAttributes[0]).SetAttribute("alt", item.Album); // Wide tile var tileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWide310x150SmallImageAndText02); var tileTextAttributes = tileXml.GetElementsByTagName("text"); tileTextAttributes[0].InnerText = item.Title; tileTextAttributes[1].InnerText = item.Album; tileTextAttributes[2].InnerText = item.Artist; tileTextAttributes[3].InnerText = CommonSharedStrings.LiveTileLine3; var tileImageAttributes = tileXml.GetElementsByTagName("image"); ((XmlElement)largeTileImageAttributes[0]).SetAttribute("src", string.IsNullOrEmpty(imageUrl) ? CommonSharedStrings.DefaultAlbumImagePath : imageUrl); ((XmlElement)tileImageAttributes[0]).SetAttribute("alt", item.Album); // Square tile var sqTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150PeekImageAndText02); var sqTileTextAttributes = sqTileXml.GetElementsByTagName("text"); sqTileTextAttributes[0].InnerText = item.Title; sqTileTextAttributes[1].InnerText = $"{item.Album} by {item.Artist}"; var sqTileImageAttributes = sqTileXml.GetElementsByTagName("image"); ((XmlElement)largeTileImageAttributes[0]).SetAttribute("src", string.IsNullOrEmpty(imageUrl) ? CommonSharedStrings.DefaultAlbumImagePath : imageUrl); ((XmlElement)sqTileImageAttributes[0]).SetAttribute("alt", item.Album); // Merge var node = largeTileXml.ImportNode(tileXml.GetElementsByTagName("binding").Item(0), true); // ReSharper disable once PossibleNullReferenceException largeTileXml.GetElementsByTagName("visual").Item(0).AppendChild(node); node = largeTileXml.ImportNode(sqTileXml.GetElementsByTagName("binding").Item(0), true); // ReSharper disable once PossibleNullReferenceException largeTileXml.GetElementsByTagName("visual").Item(0).AppendChild(node); var tileNotification = new TileNotification(largeTileXml) { ExpirationTime = DateTimeOffset.UtcNow.AddHours(2.0) }; TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification); } }
/// <summary> /// Show file properties asynchronously. /// </summary> /// <param name="databaseId">Entity ID from database.</param> public static async Task ShowFilePropertiesViewAsync(int databaseId) { DbMediaFile item = null; try { // Note: We would like to do some tricky things here in order to achieve better user experience. item = await databaseId.GetFileByIdAsync(); var file = await StorageFile.GetFileFromPathAsync(item.Path); await ShowFilePropertiesViewAsync(file); } catch (FileNotFoundException) { if (item != null) { var dialog = new MessageDialog( string.Format(CommonSharedStrings.FileNotFound, item.Path), CommonSharedStrings.Error); await dialog.ShowAsync(); } } catch (Exception ex) { var dialog = new MessageDialog(ex.Message, CommonSharedStrings.Error); await dialog.ShowAsync(); TelemetryHelper.TrackExceptionAsync(ex); } }
private async Task LaunchFolder(StorageFolder folder, DbMediaFile item) { await Launcher.LaunchFolderAsync(folder, new FolderLauncherOptions { ItemsToSelect = { await StorageFile.GetFileFromPathAsync(item.Path) } }); }
public async void Execute(object parameter) { DbMediaFile item = parameter as DbMediaFile; if (item == null && (!(parameter is int) || (item = (((int)parameter)).GetFileById()) == null)) { return; } try { var folderPath = System.IO.Path.GetDirectoryName(item.Path); var folder = await StorageFolder.GetFolderFromPathAsync(folderPath); if (folder != null) { await LaunchFolder(folder, item); } } catch { // Ignore } }
public async void UpdateInfo(DbMediaFile file) { m_smtControl.DisplayUpdater.Type = MediaPlaybackType.Music; m_smtControl.DisplayUpdater.MusicProperties.Title = file.Title; m_smtControl.DisplayUpdater.MusicProperties.AlbumArtist = file.AlbumArtist; m_smtControl.DisplayUpdater.MusicProperties.AlbumTitle = file.Album; m_smtControl.DisplayUpdater.MusicProperties.Artist = file.Artist; try { var coverStream = await ThumbnailCache.RetrieveStorageFileAsStreamAsync( await StorageFile.GetFileFromPathAsync(file.Path), true); if (coverStream != null) { using (coverStream) { m_smtControl.DisplayUpdater.Thumbnail = RandomAccessStreamReference.CreateFromStream(coverStream); m_smtControl.DisplayUpdater.Update(); return; } } } catch { } if (m_defaultPicture == null) { var coverPath = Path.Combine( Package.Current.InstalledLocation.Path, "Assets", "DefaultCover.png"); m_defaultPicture = RandomAccessStreamReference.CreateFromFile( await StorageFile.GetFileFromPathAsync(coverPath)); } m_smtControl.DisplayUpdater.Thumbnail = m_defaultPicture; m_smtControl.DisplayUpdater.Update(); }
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 SearchResultModel(DbMediaFile file) { Entity = file; Title = file.Title; Subtitle = CommonSharedStrings.Music; ItemType = CommonItemType.Song; HasThumbnail = false; Artist = file.Artist; }
static public MusicPlaybackItem CreateFromMediaFile(DbMediaFile file) { if (file == null) { throw new ArgumentNullException(nameof(file)); } return(new MusicPlaybackItem { File = file }); }
/// <summary> /// Share a file. /// </summary> /// <param name="file">The file to be shared.</param> /// <returns>An awaitable task.</returns> public static async Task ShareAsync(this DbMediaFile fileEntity) { var shareService = ShareServices.GetForCurrentView(); shareService.PrecleanForSession(); // FIXME: External file should still set this field, but they should retrieve file from MRU. // Currently no external files will be shared. await shareService.AddFileAsync(fileEntity.Path); shareService.Title = fileEntity.Title; shareService.Description = string.Format(CommonSharedStrings.GetString(SongDescriptionFieldId), fileEntity.Album, fileEntity.AlbumArtist, MiliSecToNormalTimeConverter.GetTimeStringFromTimeSpanOrDouble(fileEntity.Duration)); shareService.ShowShareUI(); }
public MediaItemChangedEventArgs(DbMediaFile file, bool isFirst, bool isLast, uint seqId) { File = file; IsFirst = isFirst; IsLast = isLast; // For compatibility if (File?.Id != null) { FileId = File?.Id.ToString(); } else { FileId = "-65535"; } Seq = seqId; }
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 { } }
/// <summary> /// Initializes new instance of <see cref="CommonViewItemModel"/> from file entity. /// </summary> /// <param name="file">Instance of <see cref="DbMediaFile"/>.</param> /// <param name="disableArtistInfo">Whether disables artist information.</param> public CommonViewItemModel(DbMediaFile file, bool disableArtistInfo = false) { if (file == null) { throw new ArgumentNullException(nameof(file)); } Title = file.Title ?? CommonSharedStrings.DefaultFileName; if (file.AlbumArtist == null) { file.AlbumArtist = CommonSharedStrings.UnknownArtistTitle; } if (file.Artist == null) { file.Artist = CommonSharedStrings.UnknownArtistTitle; } if (file.Album == null) { file.Album = CommonSharedStrings.UnknownAlbumTitle; } if (!disableArtistInfo) { Content = string.Format(CommonSharedStrings.SongSubtitleFormat, file.Album ?? CommonSharedStrings.DefaultAlbumName, file.Artist, MiliSecToNormalTimeConverter.GetTimeStringFromTimeSpanOrDouble(file.Duration)); } else { Content = MiliSecToNormalTimeConverter.GetTimeStringFromTimeSpanOrDouble(file.Duration); } InternalDbEntityId = file.Id; Type = CommonItemType.Song; ReleaseDate = file.Date; Genre = file.Genre; ExtendedFilePath = file.Path; ExtendedArtistName = file.Artist; File = file; DatabaseItemAddedDate = file.DatabaseItemAddedDate; }
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 PlaylistItem FromMediaFile(DbMediaFile file) { var item = new PlaylistItem { Title = file.Title, Artist = file.Artist, Album = file.Album, Path = file.Path, Duration = file.Duration, #if !EFCORE_MIGRATION Cue = file.MediaCue #endif }; #if !EFCORE_MIGRATION if (item.Cue != null) { item.Cue.TrackInfo = null; } #endif return(item); }
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); }
/// <summary> /// Send adaptive toast, including now playing item, to Action Center. /// </summary> /// <param name="file">To file to be sent.</param> public static void SendAdaptiveToast(DbMediaFile file) { if (file == null) { return; } if (IsAdaptiveToastSupported()) { // Start by constructing the visual portion of the toast var binding = new ToastBindingGeneric(); binding.AppLogoOverride = new ToastGenericAppLogo { Source = "DefaultCover.png", AlternateText = "Light Player logo" }; binding.Children.Add(new AdaptiveText { Text = $"Now Playing: {file.Title}", HintMaxLines = 1, HintStyle = AdaptiveTextStyle.Default }); binding.Children.Add(new AdaptiveGroup { Children = { new AdaptiveSubgroup { HintWeight = 1, Children = { new AdaptiveText { Text = $"{file.Album} - {file.Artist}", HintMaxLines = 2, HintStyle = AdaptiveTextStyle.CaptionSubtle } } } } }); // Construct the entire notification var content = new ToastContent { Visual = new ToastVisual { // Use our binding from above BindingGeneric = binding, // Set the base URI for the images, so we don't redundantly specify the entire path BaseUri = new Uri("Assets/", UriKind.Relative) }, // Include launch string so we know what to open when user clicks toast Launch = "action=viewNowPlaying", Duration = ToastDuration.Short, Audio = new ToastAudio { Silent = true } }; try { // Make sure all cleared before we send new toasts ToastNotificationManager.History.Clear(); // Generate the toast notification content and pop the toast var toastNotifier = ToastNotificationManager.CreateToastNotifier(); if (toastNotifier.Setting == NotificationSetting.Enabled) { var notification = new ToastNotification(content.GetXml()); // Only show in action center notification.SuppressPopup = true; // Now playing item should not be available for roaming notification.NotificationMirroring = NotificationMirroring.Disabled; toastNotifier.Show(notification); } } catch (Exception ex) { TelemetryHelper.TrackExceptionAsync(ex); } } }
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); }
public PlaylistEntity(DbMediaFile file) { Status = MediaPlaybackStatus.Closed; OriginEntity = file; }
public StatusChangedEventArgs(DbMediaFile currentItem, int currentIndex, MediaPlaybackStatus status) { CurrentIndex = currentIndex; CurrentItem = currentItem; Status = status; }