{"id":25416629,"url":"https://github.com/podlove/html5-audio-driver","last_synced_at":"2025-06-29T04:41:34.104Z","repository":{"id":24602709,"uuid":"102024300","full_name":"podlove/html5-audio-driver","owner":"podlove","description":"Pure HTML5 Audio Driver","archived":false,"fork":false,"pushed_at":"2024-05-23T14:12:52.000Z","size":14730,"stargazers_count":34,"open_issues_count":0,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-30T05:43:00.982Z","etag":null,"topics":["audio","composability","html5-audio"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/podlove.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-31T17:00:58.000Z","updated_at":"2023-09-03T02:39:58.000Z","dependencies_parsed_at":"2024-11-10T06:34:32.103Z","dependency_job_id":null,"html_url":"https://github.com/podlove/html5-audio-driver","commit_stats":{"total_commits":72,"total_committers":6,"mean_commits":12.0,"dds":0.09722222222222221,"last_synced_commit":"439e0d5cd1beb0d4cc598d7c1e402558084d71dd"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podlove%2Fhtml5-audio-driver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podlove%2Fhtml5-audio-driver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podlove%2Fhtml5-audio-driver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podlove%2Fhtml5-audio-driver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/podlove","download_url":"https://codeload.github.com/podlove/html5-audio-driver/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238906056,"owners_count":19550386,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio","composability","html5-audio"],"created_at":"2025-02-16T16:55:58.119Z","updated_at":"2025-02-16T16:55:58.647Z","avatar_url":"https://github.com/podlove.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pure HTML5 Audio Driver\n[![npm version](https://badge.fury.io/js/%40podlove%2Fhtml5-audio-driver.svg)](https://badge.fury.io/js/%40podlove%2Fhtml5-audio-driver.svg)\n[![Standard Style](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/feross/standard)\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fpodlove%2Fhtml5-audio-driver.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fpodlove%2Fhtml5-audio-driver?ref=badge_shield)\n\nOpinionated low level functional bindings to control html5 audio\n\n## Constraints (or what you won't find here)\n- Full functional audio player with controls and all the fuzz, instead you should use [mediaelement](https://github.com/mediaelement/mediaelement)\n- Support for multiple sounds and ambient control, instead you should use [howler.js](https://github.com/goldfire/howler.js)\n- No WebAudio, instead you should use [pizzicato](https://github.com/alemangui/pizzicato)\n\n## Features (or what you will find here)\n- Full control over the audio element\n- Functional bindings to all necessary events\n- Composability for all audio actions\n- Helper functions to get relevant audio element properties\n- Written in vanilla es6 with only one dependency to [ramda](https://github.com/ramda/ramda)\n\n## Installation\n\n`npm install html5-audio-driver` or `yarn add html5-audio-driver`\n\n## Usage\n\n### Creating an AudioElement\n\nIf you have already an audio element defined, good for you, skip this and use the dom reference. Otherwise you can use this helper, the helper will create an audio element without controls, preloading and loops:\n\n```javascript\nimport { audio } from '@podlove/html5-audio-driver'\n\nconst myAudioElement = audio([{\n  url: 'audio-files/example.m4a',\n  mimeType: 'audio/mp4'\n}, {\n  url: 'audio-files/example.mp3',\n  mimeType: 'audio/mp3'\n}, {\n  url: 'audio-files/example.ogg',\n  mimeType: 'audio/ogg'\n}])\n```\n\n`mimeType` is needed so the browser can decide what source is appropriated to use.\n\n### Interacting with the audio element\n\nAll audio element actions are curried and accept as their first parameter the audio element. Also each action returns the audio element:\n\n```javascript\nimport { compose } from 'ramda'\nimport { play, setPlaytime } from '@podlove/html5-audio-driver/actions'\n\nconst setPlaytimeAndPlay = compose(play, setAudioPlaytime)(myAudioElement)\n// Sets the playtime to 50 seconds and plays the audio\nsetPlaytimeAndPlay(50)\n```\n\nFor convenience also a `action` composer is available:\n\n```javascript\nimport { actions } from '@podlove/html5-audio-driver'\n\nconst audioActions = actions(myAudioElement)\n\naudioActions.load()\naudioActions.play()\naudioActions.pause()\naudioActions.setPlaytime(50)\naudioActions.setRate(1.5)\naudioActions.mute()\naudioActions.unmute()\n```\n\n#### Available Actions:\n\n| _Function_    | _Action_                                                  | parameters               |\n|---------------|-----------------------------------------------------------|--------------------------|\n| `play`        | Safeplays the audio, initiates load if not already loaded | void                     |\n| `pause`       | pauses the audio                                          | void                     |\n| `load`        | loads the audio                                           | void                     |\n| `mute`        | mutes the audio                                           | void                     |\n| `unmute`      | unmutes the audio                                         | void                     |\n| `setRate`     | sets the play rate                                        | number: [0.5 ... 4]      |\n| `setPlaytime` | sets the current play time                                | number: [0 ... duration] |\n\n\n### Reacting to audio events\n\nAll audio events are curried and accept as their first parameter the audio element. The second parameter is always the callback function. Each event returns a different set of audio properties, depending on the event scope:\n\n```javascript\nimport { onPlay } from '@podlove/html5-audio-driver/events'\n\nconst playEvent = onPlay(myAudioElement)\n\nplayEvent(console.log) // similar to onPlay(myAudioElement, console.log)\n/**\n* Will log audio properties on audio play:\n* {\n*  duration,\n*  buffered,\n*  volume,\n*  state,\n*  playtime,\n*  ended,\n*  rate,\n*  muted,\n*  src,\n*  paused,\n*  playing\n* }\n*/\n```\n\nFor convenience also a `events` composer is available:\n\n```javascript\nimport { events } from '@podlove/html5-audio-driver'\n\nconst audioEvents = events(myAudioElement)\n\naudioEvents.onLoading(console.log)\naudioEvents.onLoaded(console.log)\naudioEvents.onReady(console.log)\naudioEvents.onPlay(console.log)\naudioEvents.onPause(console.log)\naudioEvents.onBufferChange(console.log)\naudioEvents.onBuffering(console.log)\naudioEvents.onPlaytimeUpdate(console.log)\naudioEvents.onVolumeChange(console.log)\naudioEvents.onError(console.log)\naudioEvents.onDurationChange(console.log)\naudioEvents.onRateChange(console.log)\naudioEvents.onEnd(console.log)\n```\n\n#### Available Events:\n\n| _Function_          | _Event_                                               | _Original_        | _Callback Payload_                                                      | _Once_  |\n|---------------------|-------------------------------------------------------|-------------------|-------------------------------------------------------------------------|---------|\n| `onLoading`         | When browser starts audio loading                     | `progress`        | All props                                                               | `true`  |\n| `onLoaded`          | When browser loaded the entire file                   | `canplaythrough`  | All props                                                               | `true`  |\n| `onReady`           | When browser has enough data to play                  | `canplay`         | All props                                                               | `false` |\n| `onPlay`            | When browser starts playing audio                     | `play`            | All props                                                               | `false` |\n| `onPause`           | When browser pauses audio                             | `pause`           | All props                                                               | `false` |\n| `onEnd`             | When browser reaches end of audio                     | `ended`           | All props                                                               | `false` |\n| `onBufferChange`    | When browser buffered a new audio segment             | `progress`        | buffered segments                                                       | `false` |\n| `onBuffering`       | When browser waits for audio segments to play         | `waiting`         | All props                                                               | `false` |\n| `onPlaytimeUpdate`  | When currentTime of audio changes                     | `timeupdate`      | playtime                                                                | `false` |\n| `onVolumeChange`    | When volume of audio changes                          | `volumechange`    | volume                                                                  | `false` |\n| `onError`           | When an error occurred while playing the audio        | `error`           | `NETWORK_NO_SOURCE`, `NETWORK_EMPTY`, `NETWORK_LOADING`, `MEDIA_ERROR` | `false` |\n| `onDurationChange`  | When browser has new information on audio duration    | `durationchange`  | duration                                                                | `false` |\n| `onRateChange`      | When browser detects a change in audio playback rate  | `ratechange`      | rate                                                                    | `false` |\n| `onFilterUpdate`    | When a filter has been changed                        | `filterUpdated`   | All props                                                               | `false` |\n\n### Audio Element Properties\n\nMultiple different functions are provided to give you easy access to audio element properties. Initially most of them are undefined:\n\n```javascript\n\nimport { volume } from '@podlove/html5-audio-driver/props'\n\nisPlaying(myAudioElement) // Will return false\n```\n\nFor convenience also a composed version is available giving you all available properties:\n\n```javascript\nimport { props } from '@podlove/html5-audio-driver/props'\n\nprops(myAudioElement)\n/**\n* {\n*  duration,\n*  buffered,\n*  volume,\n*  state,\n*  playtime,\n*  ended,\n*  rate,\n*  muted,\n*  src,\n*  paused,\n*  playing\n* }\n*/\n```\n\n#### Available Properties:\n\n| _Function_  | _Description_                                     | _Return Value_                                                                                | _Initial Value_ |\n|-------------|---------------------------------------------------|-----------------------------------------------------------------------------------------------|-----------------|\n| `duration`  | Duration of audio in seconds                      | number                                                                                        | `undefined`     |\n| `buffered`  | Buffered audio segments start and end in seconds  | [[number, number], ...]                                                                       | `[]`            |\n| `volume`    | Audio volume                                      | number: [0...1]                                                                               | `undefined`     |\n| `state`     | Network State                                     | `HAVE_NOTHING`, `HAVE_METADATA`, `HAVE_CURRENT_DATA`, `HAVE_FUTURE_DATA`, `HAVE_ENOUGH_DATA`  | `undefined`     |\n| `playtime`  | Current audio playtime position in sconds         | number                                                                                        | `undefined`     |\n| `ended`     | Indicates if audio has ended                      | boolean                                                                                       | `undefined`     |\n| `rate`      | Audio playback rate                               | number: [0.5 ... 4]                                                                           | `undefined`     |\n| `muted`     | Indicates if audio is muted                       | boolean                                                                                       | `undefined`     |\n| `src`       | Used audio source                                 | string                                                                                        | `undefined`     |\n| `paused`    | Indicates if audio is paused                      | boolean                                                                                       | `undefined`     |\n| `channels`  | Available audio channels                          | number                                                                                        | `undefined`     |\n| `playing`   | Indicates if audio is playing                     | boolean                                                                                       | `false`         |\n\n\n## Handled HTML5 Quirks and Limitations (the nasty part :/)\n\nHTML5 audio was a needed addition to get rid of the flash hell. Although it is already multiple years implemented in all the different browsers each implementation has it's flaws. If you want to dive deeper into the topic I recommend you the [following article](https://24ways.org/2010/the-state-of-html5-audio).\n\n### Play Action\n\nUsing the `play` action will give you a safe function that surpresses most of the errors. One source is that older browsers doesn't implement `audio.play()` as a promise. Also there is a race condition between `play` and `pause` that needs to be `.catch`ed.\n\n### Playtime (CurrentTime)\n\nIn Safari and mobile Safari it isn't possible to set the `currentTime` before loading the audio. You can set it but it won't mutate the audio `currentTime` value. `html5-audio-driver` therefore uses a custom `playtime` attribute that is synced wit the `currentTime`.\n\n### Mobile Environments\n\nTo `play` audio on mobile devices you have to trigger use a direct user interaction to trigger the audio. Also `volume` is not available on mobile devices.\n\n## Legacy Browser Support (IE11)\n\nIn case you need IE11 support you have to provide some polyfills in your application. Have a look at the [test polyfills](test/polyfills.js) to see a working example.\n\n## Publishing\n\nRun `npm publish:prepare` move to the `dist/` folder and run `npm publish --public`\n\n\n## License\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fpodlove%2Fhtml5-audio-driver.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fpodlove%2Fhtml5-audio-driver?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpodlove%2Fhtml5-audio-driver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpodlove%2Fhtml5-audio-driver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpodlove%2Fhtml5-audio-driver/lists"}