다음을 통해 공유


Access media libraries (Windows Runtime apps)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

Discover stored photos, music, and videos by using the guidance in this topic.

Media libraries

Devices provides five predefined locations for users and apps to store media files. Built-in apps store both user-created media and downloaded media in these locations.

The locations are:

  • Pictures Library. Contains pictures.

    • Camera Roll. Contains photos and video from the built-in camera.

    • Saved Pictures. Contains pictures that the user has saved from other apps.

  • Music Library. Contains songs, podcasts, and audio books.

  • Video Library. Contains videos.

Users or apps may also store media files outside the media library folders on the SD card. To find a media file reliably on the SD card, scan the contents of the SD card, or ask the user to locate the file by using a file picker. For more info, see Access the SD card.

Querying the media libraries

Query results include both internal and removable storage

Users can choose to store files by default on the optional SD card. Apps, however, can opt out of allowing files to be stored on the SD card. As a result, the media libraries can be split across the device's internal storage and the SD card.

You don't have to write additional code to handle this possibility. The methods in the Windows.Storage namespace that query known folders transparently combine the query results from both locations. You don't have to specify the removableStorage capability in the app manifest file to get these combined results.

Consider the state of the device's storage shown in the following image:

If you query the contents of the Pictures Library by calling await KnownFolders.PicturesLibrary.GetFilesAsync(), the results include both internalPic.jpg and SDPic.jpg.

Deep queries

Use the deep queries to enumerate the entire contents of a media library quickly.

The deep queries return only files of the specified media type. For example, if you query the Music Library with a deep query, the query results do not include any picture files found in the Music folder.

On devices where the camera saves both a low-resolution image and a high-resolution image of every picture, the deep queries return only the low-resolution image.

The Camera Roll and the Saved Pictures folder do not support the deep queries.

The following deep queries are available:

Pictures library

  • GetFilesAsync(CommonFileQuery.OrderByDate)

Music library

  • GetFilesAsync(CommonFileQuery.OrderByName)
  • GetFoldersAsync(CommonFolderQuery.GroupByArtist)
  • GetFoldersAysnc(CommonFolderQuery.GroupByAlbum)
  • GetFoldersAysnc(CommonFolderQuery.GroupByAlbumArtist)
  • GetFoldersAsync(CommonFolderQuery.GroupByGenre)

Video library

  • GetFilesAsync(CommonFileQuery.OrderByDate)

Flat queries

To get a complete listing of all the files and folders in a library, call GetFilesAsync(CommonFileQuery.DefaultQuery). This method returns all files in the library, regardless of their type. This is a shallow query, so you have to enumerate the contents of subfolders recursively if the user has created subfolders in the library.

Use flat queries to return media files of types that are not recognized by the built-in queries, or to return all the files in a library, including files that are not of the specified type. For example, if you query the Music Library with a flat query, the query results include any picture files found by the query in the Music folder.

Sample queries

Assume that the device and its optional SD card contain the folders and files shown in the following image:

Here are a few examples of queries and the results that they return.

Query Results

KnownFolders.PicturesLibrary.GetItemsAsync();

  • Camera Roll folder from internal storage
  • Camera Roll folder from the SD card
  • Saved Pictures folder from internal storage
  • Saved Pictures folder from the SD card

This is a flat query, so only immediate children of the Pictures folder are returned.

KnownFolders.PicturesLibrary.GetFilesAsync();

No results.

This is flat query, and the Pictures folder does not contain any files as its immediate children.

KnownFolders.PicturesLibrary.GetFilesAsync(CommonFileQuery.OrderByDate);

  • 4-3-2012.jpg file from the SD card
  • 1-1-2014.jpg file from internal storage
  • 1-2-2014.jpg file from internal storage
  • 1-6-2014.jpg file from the SD card

This is a deep query, so the contents of the Pictures folder and of its child folders are returned.

KnownFolders.CameraRoll.GetFilesAsync();

  • 1-1-2014.jpg file from internal storage
  • 4-3-2012.jpg file from the SD card

This is a flat query. The ordering of the results is not guaranteed.

 

Media library capabilities and file types

Here are the capabilities that you can specify in the app manifest file to access media files in your app.

  • Music. Specify the Music Library capability in the app manifest file to let your app see and access files of the following file types:

    • .qcp
    • .wav
    • .mp3
    • .m4r
    • .m4a
    • .aac
    • .amr
    • .wma
    • .3g2
    • .3gp
    • .mp4
    • .wm
    • .asf
    • .3gpp
    • .3gp2
    • .mpa
    • .adt
    • .adts
    • .pya
  • Photos. Specify the Pictures Library capability in the app manifest file to let your app see and access files of the following file types:

    • .jpeg
    • .jpe
    • .jpg
    • .gif
    • .tiff
    • .tif
    • .png
    • .bmp
    • .wdp
    • .jxr
    • .hdp
  • Videos. Specify the Video Library capability in the app manifest file to let your app see and access files of the following file types:

    • .wm
    • .m4v
    • .wmv
    • .asf
    • .mov
    • .mp4
    • .3g2
    • .3gp
    • .mp4v
    • .avi
    • .pyv
    • .3gpp
    • .3gp2

Working with photos

On devices where the camera saves both a low-resolution image and a high-resolution image of every picture, the deep queries return only the low-resolution image.

The Camera Roll and the Saved Pictures folder do not support the deep queries.

Opening a photo in the app that captured it

If you want to let the user open a photo again later in the app that captured it, you can save the CreatorAppId with the photo's metadata by using code similar to the following example. In this example, testPhoto is a StorageFile.

  IDictionary<string, object> propertiesToSave = new Dictionary<string, object>();

  propertiesToSave.Add("System.CreatorOpenWithUIOptions", 1);
  propertiesToSave.Add("System.CreatorAppId", appId);
 
  testPhoto.Properties.SavePropertiesAsync(propertiesToSave).AsyncWait();   

Using stream methods to add a file to a media library

When you access a media library by using a known folder such as KnownFolders.PictureLibrary, and you use stream methods to add a file to the media library, you have to make sure to close all the streams that your code opens. Otherwise these methods fail to add the file to the media library as expected because at least one stream still has a handle to the file.

For example, when you run the following code, the file is not added to the media library. In the line of code, using (var destinationStream = (await destinationFile.OpenAsync(FileAccessMode.ReadWrite)).GetOutputStreamAt(0)), both the OpenAsync method and the GetOutputStreamAt method open a stream. However only the stream opened by the GetOutputStreamAt method is disposed as a result of the using statement. The other stream remains open and prevents saving the file.

StorageFolder testFolder = await StorageFolder.GetFolderFromPathAsync(@"C:\test");
StorageFile sourceFile = await testFolder.GetFileAsync("TestImage.jpg");
StorageFile destinationFile = await KnownFolders.CameraRoll.CreateFileAsync("MyTestImage.jpg");
using (var sourceStream = (await sourceFile.OpenReadAsync()).GetInputStreamAt(0))
{
    using (var destinationStream = (await destinationFile.OpenAsync(FileAccessMode.ReadWrite)).GetOutputStreamAt(0))
    {
        await RandomAccessStream.CopyAndCloseAsync(sourceStream, destinationStream);
    }
}

To use stream methods successfully to add a file to the media library, make sure to close all the streams that your code opens, as shown in the following example.

StorageFolder testFolder = await StorageFolder.GetFolderFromPathAsync(@"C:\test");
StorageFile sourceFile = await testFolder.GetFileAsync("TestImage.jpg");
StorageFile destinationFile = await KnownFolders.CameraRoll.CreateFileAsync("MyTestImage.jpg");

using (var sourceStream = await sourceFile.OpenReadAsync())
{
    using (var sourceInputStream = sourceStream.GetInputStreamAt(0))
    {
        using (var destinationStream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            using (var destinationOutputStream = destinationStream.GetOutputStreamAt(0))
            {
                await RandomAccessStream.CopyAndCloseAsync(sourceInputStream, destinationStream);
            }
        }
    }
}

Access the SD card