Note that this specification is an unofficial draft and that the W3C System Applications WG at this moment is not taking up this work.
This API provides webapps with access to media files in the device through a MediaDB interface for each media type, images, videos or music. Each media file is represented by a MediaDBRecord, which includes name, size, type, modification date and metadata (image thumbnails, song titles, etc) of the stored files.
Compared to directly using the W3C file API's for in media handling webapps this API provides a simpler interface and better performance.
The specification is partly inspired by Firefox OS MediaDB API, which is a library that integrates both the Firefox OS DeviceStorage API and the W3C IndexedDB API into a single API. However, the ambition with this specification is to define an API that is independent on any other underlying API, except the W3C File API [[!FILE-API]]), that is subject for W3C standardization and that could be implemented in any web user agent.
Examples of webapps that using this API are:
This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.
Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]], as this specification uses that specification and terminology.
The term webapp refers to a Web application, i.e. an application implemented using Web technologies, and executing within the context of a Web user agent, e.g. a Web browser or other Web runtime environment.
The Promise
interface provides asynchronous access to the result of an operation
that is ongoing, has yet to start, or has completed, as defined in
[[!ES6]].
The
EventHandler
interface represents a callback used for event handlers
as defined in [[!HTML5]].
The concepts queue a task and fire an event are defined in [[!HTML5]].
The terms event handler and event handler event types are defined in [[!HTML5]].
The File
interface is defined in [[!FILE-API]].
The Blob
interface is defined in [[!FILE-API]].
This is a security and privacy sensitive API and a webapp must
have permission to use the API. Permission to access a media database
for a media type is requested through the MediaStorage.get
method. The manner in which permission is given or not varies depending
on the type of web runtime environment in which this API is implemented
and could be based on:
The manner in which permission to use this API differs depending on the type of web runtime it is implemented in. For example, a web runtime for secure installed web applications may be able to open up this API so that no explicit user content is needed, while an implementation in a web browser may use a combination of web security mechanisms, such as secure transport (https:), content security policies (CSP) and a signed manifest, and user consent to open up the API. The Permissions API, which currently is an unofficial draft, is an API that allows a web application to be aware of the status of a given permission, to know whether it is granted, denied or if the user will be asked whether the permission should be granted or not. If this API gets consensus and becomes a W3C standard, and also is extended to support permission requests, it may be possible to use his API for permission to the MediaStorage API. W3C has activities on Trust and permissions. For example, see Workshop on trust and permissions for Web applications 3–4 September 2014, Paris, France and the proposed Community Group as well as Requirements for Powerful Features.
This interface exposes the get()
method to retrive the
media database for a type of media (images, videos or audio).
This method MUST return a Promise and then run the following steps asynchronously:
getMediaStoragePromise
,
return it and run the remaining steps asynchronously.getMediaStoragePromise
with DOMException TBD and abort the remaining steps.getMediaStoragePromise
with the
MediaDB object as argument. Selection of media storage areas and user permission may have to be further investigated. See for example Chrome mediaGalleries getMediaFileSystems and addUserselectedFolder and Tizen Content API getDirectories.
This interface defines an object that represents the media storage for either "images", "videos" or "audio".
ready
event,
which is fired when the MediaDB object is ready to use.unavailable
event,
which is fired when the when the media storage becomes unavailable.
The MediaDB state
attribute states the detailed
reason for the unavailable MediaDB. It is one the values
nocard
or unmounted
.created
event,
which is fired when one or more files were created. deleted
event,
which is fired when one or more files were deleted. scanstart
event,
which is fired when scanning for new and deleted files starts. scanend
event,
which is fired when scanning for new and deleted files ends. partlyunavailable
event, which is fired when a storage area becames permanently
unavailable but one or more other storage areas are still
available. This happens for example when an SD-card
is removed but the internal memory is still available.
enumerate()
method. All fields
are optional.
created
events. If the
scan finds that files have been deleted, it reports them with one or
more deleted
events. Scanning is performed continuously
in the background but the frequency of the scanning is platform dependent.
Client webapps could use this method to assure that the media
database gets updated.
This method must return a Promise and then run the following steps asynchronously:
scanPromise
,
return it and run the remaining steps asynchronously.scanstart
at the MediaDB object.scanPromise
with DOMException TBD, abort the remaining steps and
fire an event named scanend
at
the MediaDB object .created
events.
If the scan finds that files have been deleted, it reports
them with one or more deleted
events. scanPromise
with no argument and fire an event named
scanend
at the MediaDB object.
It must be further investigated if this method is needed. Normally
the UA performs scanning in the background. However, for certain
big storage areas it might be needed to have a user/application
controlled start of scanning. The need for the scanstart
and scanend
events must also be investigated.
This method must return a Promise and then run the following steps asynchronously:
getFileInfoPromise
,
return it and run the remaining steps asynchronously.getFileInfoPromise
with DOMException TBD and abort
the remaining steps.getFileInfoPromise
with the MediaDBRecord object as argument.
Needs to be investigated. Should we have an
argument stating if the metadata of only the MediaDBRecord
should be updated or if both the MediaDBRecord and the
file itsel should be updated? What happens if two applications
simultaneously changes the metadata of a file?
.
Note that FFOS MediaDB does only allows the update of metadata in
the IDB, not for the file itself. The Tizen Content API
(see https://developer.tizen.org/documentation/dev-guide/2.2.1?redirect=https://developer.tizen.org/dev-guide/2.2.1/org.tizen.web.appprogramming/html/api_reference/api_reference.htm,
Web Device API reference, Content API, interface Content, defines
an array of "editableAttributes" but the metadata of the file can
not be updated. See the update() method. The Chrome media galleries
API, https://developer.chrome.com/apps/mediaGalleries, does not
provide a method for updating metadata.
This method must return a Promise and then run the following steps asynchronously:
updateMetadataPromise
,
return it and run the remaining steps asynchronously.updateMetadataPromise
with DOMException TBD and abort the remaining steps.metdata
attribute
with the provided metadata, update the File object
and resolve updateMetadataPromise
with no
arguments.created
event is also fired.
This method MUST run the following steps asynchronously:
addPromise
,
return it and run the remaining steps asynchronously.addPromise
with DOMException TBD and abort
the remaining steps.fileName
parameter is present the
name
attribute of the new File object
added to the media storage is set to the value of the
fileName
parameter. Note that the
name
attribute of the new File object
includes the path to the file in the file system. fileName
parameter is not present the
name
attribute of the File object added
to the media storage is generated automatically.created
at the
MediaDB object and resolve addPromise
with the stored MediaDBRecord object as argument.image
, video
or audio
mime
type.
true
overwrite with the new file. If
false
reject the returned Promise with error
TBD. .
deleted
event
is fired if successful.
This method must return a Promise and then run the following steps asynchronously:
deletePromise
,
return it and run the remaining steps asynchronously.deletePromise
with DOMException TBD and abort
the remaining steps.deleted
at
the MediaDB object and resolve
deletePromise
with no arguments.
This method must return a Promise and then run the following steps asynchronously:
countPromise
,
return it and run the remaining steps asynchronously.countPromise
with DOMException TBD and abort
the remaining steps.countPromise
with the number of records
(unsigned long) as argument.
To we need further filtering options?
This method must return a Promise and then run the following steps asynchronously:
freeSpacePromise
,
return it and run the remaining steps asynchronously.freeSpacePromise
with DOMException TBD and abort
the remaining steps.freeSpacePromise
with the number of
bytes available (unsigned long) as argument.
MediaDB automatically scans the file system (internal
and/or external) for new and deleted files and updates the media
database. The scanning is performed in the background and the
scanning frequeny is platform dependent. More capable platforms
could immediately discover changes to the files and update the media
database, while less capable platforms may scan less frequently.
There is also a "manual" scan()
method allowing client
webapps to start a scanning of the file system in order to
assure that the media database is updated.
If the scan finds new files, it reports them to the client webapp
with one or more created
events. If the scan finds that
files have been deleted, it reports them with one or more
deleted
events.
MediaDB fires a scanstart
event when a scan
begins and fires a scanend
event when the scan is complete.
Client webapps can use these events to let the user know that a
scan is in progress.
Below is a list of event handler and corresponding event handler event types that MUST be supported as attributes by the MediaDB object.
event handler | event handler event type |
---|---|
onready |
ready |
onunavailable |
unavailable |
oncreated |
created |
ondeleted |
deleted |
onscanstart |
scanstart |
onscanend |
scanend |
onpartlyunavailable |
partlyunavailable |
The ready
event MUST be fired whenever the MediaDB object
becomes ready to use.
The unavailable
event MUST be fired whenever the MediaDB
object becomes unavailable. The MediaDB state
attribute states the detailed reason for the unavailable MediaDB.
It is one the values nocard
or unmounted
.
The created
event MUST be fired when one or more files were
created. This event MUST implement the CreatedEvent interface.
The deleted
event MUST be fired when one or more files
were deleted.The deleted
event MUST implement the
DeletedEvent interface.
When several files are deleted the UA could send one event per deleted file or one event with an array of names of files deleted. This should be further specified but it is a performance issue and depends on platform. Our implementation should be evaluated.
If MediaDB detects that a file has been modified in place
(because its size, date or any metadata changed) it treats this as
a deletion of the old version and the creation of a new version,
and will fire a deleted
event followed by a
created
event.
The created
and deleted
events are not
triggered until the corresponding files have actually been created
and deleted and their mediaDBRecord objects have been updated.
The scanstart
event MUST be fired when scanning for
new and deleted files starts.
The scanend
event MUST be fired when scanning for
new and deleted files ends.
The partlyunavailable
event MUST be fired when a storage
area becames permanently unavailable but one or more other storage
areas are still available. This happens for example when an SD-card
is removed but the internal memory is still available.
The FFOS MediaDB API sends a series of deleted events for all of the files that are no longer available due to the removed storage area. Do we want the same behaviour here? Or do we want another behaviour, e.g. stating that the application is required to call enumerate() to get the fresh staus of the media storage?
Consider to integrate event handling with Service Workers. See https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#extensibility
MediaDB stores a MediaDBRecord object representing each
stored media file of the appropriate media type and mime type. Note that
the records do not include the file itself, but only its name. Client
webapps should use the getFile()
method to retrieve
the File object.
This method must return a Promise and then run the following steps asynchronously:
getFilePromise
, return it
and run the remaining steps asynchronously.getFilePromise
with DOMException TBD and abort
the remaining steps.file
be a new File object. Resolve
getFilePromisePromise
with file
as
argument. Metadata related to the MediaDBRecord objects. This interface is not used directly. Instead Media type specific metadata interfaces that inherits this base metadata interface is defined.
Metadata for audio files.
To be completed with remaining audio metadata attributes for example inspired by Android MediaStore API, audio: http://developer.android.com/reference/android/provider/MediaStore.Audio.AudioColumns.html.
Metadata for image files.
To be completed with remaining image metadata attributes for example inspired by Android MediaStore API, image: http://developer.android.com/reference/android/provider/MediaStore.Images.ImageColumns.html
Metadata for video files.
To be completed with remaining video metadata attributes for example inspired by Android MediaStore API, video: http://developer.android.com/reference/android/provider/MediaStore.Video.VideoColumns.html
The callback is called once for each entry in the media storage.
enumerate()
method is fulfilled.
The CreatedEvent interface represents events related to one or
more files of the associated media type added to the file system.
The event's attribute is an array of MediaDBRecords corresponding
to the added files. When a single file is created (for example when
the user takes a picture with the Camera app) this array has only a single
element. But when MediaDB scans for new files it may batch multiple
records into a single CreatedEvent. If a created
event has many records, apps may choose to simply rebuild their UI
from scratch with a new call to enumerate()
instead of
handling the new files one at a time.
The DeletedEvent interface represents events related to one or
more files of the associated media type deleted from the file system.
The event's attribute is an array of the names of the files that have
been deleted. As with created
events, the array may
have a single element or may have many batched elements.
Options for the enumerate()
method. All fields are optional.
To we need a filter field? If so, how does it look like? Something like the filter argument in the Tizen Content API, https://developer.tizen.org/documentation/dev-guide/2.2.1?redirect=https://developer.tizen.org/dev-guide/2.2.1/org.tizen.web.appprogramming/html/api_reference/api_reference.htm ?
TBD.