Galactic is a generic media library that is strictly based on the HtmlMediaElement implementation. It supports HTML5 Audio, <audio>
element, and video streaming (mp4 & HLS).
It makes it easier on developers to manage huge playlists, and to create player-like behavior really simple and easy.
It simply reloads the current media instance when facing any error and also after losing internet connection.
Very easy to setup in any JavaScript project - straight forward implementation.
A pleasure to give you one smooth experience to work with either audio or video across all web browsers.
Usually, users face slow connections and the handshake between the web browser and the media server tend to be unsuccessful, which prompt them to refresh the page in order to continue their music experience.
In addition to those obstacles, developers confront the usual browser issues when working with media, and the regular development of workarounds to overcome such matters.
Demo: Galactic Demo
Anghami, the leader in online media streaming in the MENA region, uses Galactic as a media player.
The bundle is less than 30kb and is increased by 75% when compressed through gzip.
- The
play()
must be initiated by a user gesture event - The
play()
request was interrupted by a call topause()
- Online / Offline reloading
- Advanced error handling for perfect asynchronous media streaming
- Fast media download across all JavaScript supported browsers
- Works on browsers that doesn't support native HLS video streaming - use
hls.js
as a polyfill
Unlocks the infamous browsers error: The play()
must be initiated by a user gesture event
const myTrack;
// A nice trick to be able to play() without a user gesture event on mobile
// Mobile browsers do not allow applications to play HTML5 audio without an explicit action by the user
const loadedEmpty = galatic.loadEmpty(); // for mobile only
fetch(myTrack).then( url => {
galatic.load(url); // plays by default
//or
galactic.load(url).play();
});
Prop Name | Type | Default | Usage |
---|---|---|---|
reloadOnInit | Number In Milliseconds | 10000 | Reload time value for on init failure |
reloadOnError | Number In Milliseconds | 5000 | Reload time value for on error failure |
reloadCount | Number | 5 | How many times the media is reloaded |
playOnLoad | boolean | true | If false , media is paused after load |
volume | Number | 1 | Value from 0 to 1 |
fadeIn | boolean | false | Fade in the last few seconds |
onInit | Function | Called on initialization | |
html5 | boolean | true | Either or new Audio() |
video | boolean | True to switch to <video> |
|
poster | string | URL for the <video> background |
|
hls | boolean | false | Turn on HLS streaming |
Loads a media file from a source url - accepts m4a, mp4, mpeg4, aac, flv, mov, m4v, f4v, m4b, mp4v, 3gp, 3g2, mp4, m3u8.
Reload the media file and plays from the given time if any.
Adjusts the current time value of the media file to a given value in milliseconds.
Sets the volume of the player to a value between 0 and 1.
Plays the media file.
Pauses the playing media object. forcePause is passed if the object is expected to be paused after loading.
Stops the media object, then flushes all the variables, and resets the media src url. Dispatches an event durationChange with progress, remainingTime, and position time values set to 0. Accepts a callback function to be called after cleansing the environment.
Increases the index of either the shuffle list or the current playing list. If a callback function is passed, it will be called after iterating through the desired Array list.
Decreases the index of either the shuffle list or the current playing list. If a callback function is passed, it will be called after iterating through the desired Array list.
Switches repeat on and calls a callback method if any.
Shuffles the playlist and turns shuffle on. Calls a callback if a method is provided with an object that looks like this:
{
track: Object,
list: Array<Object>
}
Dispatches an event called shuffle status change with an object as the following:
{
shuffle: boolean, // true
track: Object
}
Toggles repeat off then iterates backwards through the shuffle list, if shuffle is on, or the current playing list. A callback method is called if one is provided.
This methods does four checks.
First, if there is a next playing item and shuffle is on, it picks the shuffled track from the nextPlayingList, else it picks the regular next item from the nextPlayingList.
Second, if repeat is on, then then sama media file plays plays again.
Third, if shuffle is on, it shuffles and increases the shuffle index.
Fourth, it just increases the current index of the playing list.
Returns the current item from the next playing list.
Concats either a track object or an additional playlist on top of the next playing list.
Pushes a callback to be dispatched upon a certain event.
Note: You can attach as many events of the same name as you want.
Event names which can also be used when clearing the event name by using off():
error
, play
, pause
, end
, wait
, whilePlaying
, readyToPlay
, rateChange
, volumeChange
, durationChange
, repeatStatusChange
, playlistChange
, bufferChange
Clears the current events list which belongs to a specific type, and fills it with a given null or any value.
Concats either a track item or another playlist on top of the existing shuffle or regular playing list. Calls a callback if a function is provided. Dispatches an event called "playlistChange" with an object as follows:
{
playlist: Array<Object>,
shuffleList: Array<Object>
}
Clears either the shuffle or the regular list and calls a callback method if there is one. Emits an event called "playlistChange" with an object as follows:
{
'shuffleList' | 'list': Array<Object> // an empty []
}
Sets the <audio>
or <video>
element attribute with a given string value.
Removes a given attribute from the <audio>
or <video>
element.
Name | Type | Notes |
---|---|---|
audioElement | HTMLMediaElement | |
list | Array | |
shuffleList | Array | |
playNextList | Array | |
currentMediaItem | Object | |
options | Object | |
currentSrc | string | |
audioTrackPlaying | boolean | true: playing, |
false: paused, | ||
undfined: loading | ||
isRepeating | boolean | |
isShuffling | boolean | |
isReloading | boolean | |
isPaused | boolean | |
forceDurationChangeForAudioAd | boolean | |
currentIndex | number | |
shuffleIndex | number | |
progress | number | |
position | number | |
duration | number | |
remainingTime | number | |
bufferProgress | number |
import { Galactic } from "Galactic":
// or
declare const Galactic;
var galatic = new Galactic().init({
//optional
reloadOnInit: "Numner In Milliseconds", // defaults to 10000
reloadOnError: "Numner In Milliseconds", // defaults to 5000
reloadCount: "Integer", // defaults to 5
playOnLoad: true | false, // defaults to true
volume: "Integer 0 -> 1", // defaults to 1
fadeIn: true | false, // defaults to false
onInit?: Function,
//just for audio + defaults to audio
html5: true | false,
// defaults to true, if false an HTML <audio> element is appended // to the <body>
//just for video
video: true,
poster: "any image url",
hls: true | false, //defaults to false
}).setPlaylist(myArrayOfSongs, function () {
//do anything
});
galatic.on('end', function () {
// In some cases, when the song reaches the end, you may want to either shuffle if shuffle is on, repeat if repeat is on, or simply move to the next song
// Use galatic.applyNextAction(callback);
});
galatic.on('durationChange', function (data) {
progressElement.value = data.progress;
position.innerHTML = humanTime(data.position);
remaining.innerHTML = humanTime(data.remainingTime);
});
galatic.on('play', (audioTrackPlaying: boolean) => {
console.log('on play.........'); // audioTrackPlaying: true
});
galatic.on('pause', (audioTrackPlaying: boolean) => {
console.log('on pause.........'); // audioTrackPlaying: false
});
galatic.on('bufferChange', data => {
console.log('on bufferChange: ', data.bufferProgress);
});
galatic.on('wait', (audioTrackPlaying: undefined) => {
console.log('is waiting.........');
});
// Error that cannot be handled by Galatic .i.e when the src is not supported
galatic.on('error', _ => {
console.log('on fatal error.........');
});
galatic.on('readyToPlay', _ => {
console.log('is ready to play.........');
});
function previousAction() {
galatic.applyPreviousAction(function (data) {
fetchplay(data.track);
});
}
const previousClickFn = function () {
// handled by default in the player class since the default actions always moves forward so that's wwhy it's handled there
// galatic.isRepeating && galatic.toggle('repeat', false);
previousAction();
};
function nextAction() {
galatic.applyNextAction(function (data) {
fetchplay(data.track);
});
}
const nextClickFn = () => {
if (galatic.isRepeating) {
galatic.toggle('repeat', false);
}
nextAction();
};
// Just toggle the `shuffle` property and let Galatic shuffle through the list
const shuffle = () => {
galatic.toggle('shuffle');
// or
galatic.shuffle(function (data) {
// do whatever
});
};
const repeat = () => {
galatic.toggle('repeat');
};