Skip to content

omnisense/omnisong API reference

Floor
Family
Version
1.x
Verified for real
Its README does not say
Licence
MIT
composer require omnisense/omnisong:1.x-dev

Read from the package's own PHP files at the commit 8be4dc647fc0: its namespaces, classes, interfaces and enums, their public constants, properties and methods with their PHPDoc, and the options its factories take. Nothing of it is run.

Omnisong

  • Config class

    A catalogue's configuration while its factory builds it: the options given, the factory's defaults under them, and the keys that must be filled.

    3 methods

  • Platform enum

    Where a recording can be listened to or bought. The label comes first: a site shows "released by ES-DUR, buy it there" before "listen on Spotify". rank() orders a PlatformLinks; fromOdesli() maps song.link's keys; embeddable() says whether Player\Embedder knows an iframe for it.

    5 methods · 24 cases

  • Registry class

    The catalogues by name, each built once from its factory and options:

    6 methods

Omnisong\Bridge\Symfony

  • OmnisongBundle class

    Omnisong in a Symfony application: the catalogue packages installed (omnisong/odesli, omnisong/itunes) registered, the catalogues built from configuration and asked in that order by the one CatalogInterface that is autowired, the Embedder with the site's theme, and the Twig functions:

    3 methods

Omnisong\Bridge\Twig

Omnisong\Catalog

  • Catalog class

    Every configured catalogue asked in turn, their answers merged: Odesli gives the links, iTunes the tracks and their previews, and the label the site knows goes first. What one catalogue cannot do the next does; a catalogue that is down is skipped, and remembered as skipped so the caller does not cache a half answer (see $incomplete).

    6 methods · 1 property

  • CatalogFactory class

    The Omnibus way, at its simplest: a catalogue's factory fills a Config - its name ("omnisong.factory_name"), the options it needs ("omnisong.required_options") and their defaults - then builds the catalogue from it, on the application's HTTP client when one is given.

    4 methods

  • CatalogFactoryInterface interface

    Builds a catalogue from its options (a key, a country...).

    2 methods

  • CatalogInterface interface

    A service that knows recordings: where they are (the links), what they are (a release with its tracks and previews), what an artist put out.

    4 methods

Omnisong\Exception

  • InvalidConfigException class

    A catalogue misconfigured: a key missing, an unknown factory.

  • InvalidReferenceException class

    A value Reference::parse() cannot read: neither a URL, a UPC/EAN nor an ISRC.

  • NotSupportedException class

    The catalogue does not read that kind of reference, or does not do that at all.

    2 methods

  • OmnisongException interface

    Every exception Omnisong throws.

  • ProviderException class

    The catalogue's service answered with an error.

    1 method · 2 properties

  • RateLimitedException class

    The service asks to slow down (Odesli: 10 requests a minute without a key).

    1 method · 1 property

  • UnavailableException class

    The service could not be reached, or is down: never "not found". A caller that caches an answer must not cache this one.

Omnisong\Http

  • Redaction class

    What a failed call may carry of its credentials, taken out before the failure leaves the package: an HTTP client's exception quotes the URL called (a key in its query, a password in its user part), and every exception's trace keeps the arguments of the calls under it (the request options, headers and query with the key) unless PHP runs with zend.exception_ignore_args.

    5 methods · 1 constant

Omnisong\Model

  • Artist class

    A performer as a catalogue names it, with its ids on the platforms that gave one.

    1 method · 4 properties

  • Embed class

    An iframe that plays from a platform: its markup, its size, where it loads from (for a CSP).

    1 method · 5 properties

  • Label class

    The label a release came out on: who to show first, and where its shop is.

    1 method · 3 properties

  • PlatformLink class

    One place the recording is: the platform, the URL, the platform's own id when known.

    2 methods · 5 properties

  • PlatformLinks class

    The links of one recording, one per platform, in the order a site shows them: the label first, then the shops, then the streamers (Platform::rank()).

    14 methods

  • Reference class

    What a catalogue is asked about: a URL on any platform, an ISRC (a recording), a UPC/EAN (a release), or a platform's own id. One of them is enough; a catalogue that cannot read the kind given says so (NotSupportedException).

    7 methods · 2 constants

  • Release class

    An album, a single, an EP as the catalogues know it: its title, its artist, its label, the UPC that names it, its cover, its tracks, and the links to every platform (the label's first).

    5 methods · 13 properties · 3 constants

  • Source class

    Something an <audio> element can play: a file of the site's, or a catalogue's preview.

    1 method · 4 properties · 2 constants

  • Track class

    One recording of a release: its place, its title, who plays, the ISRC that names it everywhere, and the preview a catalogue offers (iTunes: 30 seconds, licensed for that use).

    2 methods · 10 properties

Omnisong\Player

  • EmbedOptions class

    How an embed should look: the theme of the page it sits in, compact or full, autoplay (only after a click).

    2 methods · 5 properties · 2 constants

  • Embedder class

    The platforms' own players, from their public embed URLs - no key, no SDK: Spotify (open.spotify.com/embed: albums, tracks, playlists, artists), Apple Music (embed.music.apple.com), Deezer (widget.deezer.com), YouTube (youtube-nocookie.com), SoundCloud (w.soundcloud.com). Every iframe is lazy and sandboxed as the platform requires; a site loads it on a click, never with the page.

    3 methods

  • EmbedderInterface interface

    Turns a platform link into the iframe that plays it - without any key, for the platforms that allow it.

    2 methods

Omnisong

Config class

final class Config extends ArrayObject Config.php:13

A catalogue's configuration while its factory builds it: the options given, the factory's defaults under them, and the keys that must be filled.

Config::defaults()

public function defaults(array $defaults): self

Sets each key not set yet.

Config::validateNotEmpty()

public function validateNotEmpty(array $keys): void

Config::get()

public function get(string $key, mixed $default = null): mixed

Platform enum

enum Platform Platform.php:11

Where a recording can be listened to or bought. The label comes first: a site shows "released by ES-DUR, buy it there" before "listen on Spotify". rank() orders a PlatformLinks; fromOdesli() maps song.link's keys; embeddable() says whether Player\Embedder knows an iframe for it.

case LABEL = 'label'
case SHOP = 'shop'
case BANDCAMP = 'bandcamp'
case SPOTIFY = 'spotify'
case APPLE_MUSIC = 'apple_music'
case ITUNES = 'itunes'
case YOUTUBE = 'youtube'
case YOUTUBE_MUSIC = 'youtube_music'
case DEEZER = 'deezer'
case QOBUZ = 'qobuz'
case IDAGIO = 'idagio'
case TIDAL = 'tidal'
case AMAZON_MUSIC = 'amazon_music'
case AMAZON = 'amazon'
case PRESTO = 'presto'
case HIGHRESAUDIO = 'highresaudio'
case SOUNDCLOUD = 'soundcloud'
case NAPSTER = 'napster'
case PANDORA = 'pandora'
case ANGHAMI = 'anghami'
case BOOMPLAY = 'boomplay'
case AUDIOMACK = 'audiomack'
case AUDIUS = 'audius'
case OTHER = 'other'

Platform::rank()

public function rank(): int

Lower first. The label, then the shops, then the streamers by weight in classical music.

Platform::label()

public function label(): string

Platform::embeddable()

public function embeddable(): bool

Whether the core's Embedder knows an iframe for it (no key needed).

Platform::fromOdesli()

public static function fromOdesli(string $key): ?self

song.link's platform keys (linksByPlatform) to ours; null for one we do not list.

Platform::fromUrl()

public static function fromUrl(string $url): ?self

The platform a URL belongs to, from its host; null when unknown.

Registry class

final class Registry Registry.php:17

The catalogues by name, each built once from its factory and options:

new Registry([new OdesliCatalogFactory($http), new ItunesCatalogFactory($http)], [ 'odesli' => ['factory' => 'odesli', 'options' => ['api_key' => null]], 'itunes' => ['factory' => 'itunes', 'options' => ['country' => 'de']], ]);

Registry::__construct()

public function __construct(iterable $factories, readonly array $config)

Registry::get()

public function get(string $name): CatalogInterface

Registry::has()

public function has(string $name): bool

Registry::names()

public function names(): array

Registry::all()

public function all(): array
Returns

in the configured order

Registry::factories()

public function factories(): array
Returns

the factories installed: what factory: may name

Omnisong\Bridge\Symfony

OmnisongBundle class

final class OmnisongBundle extends AbstractBundle OmnisongBundle.php:44

Omnisong in a Symfony application: the catalogue packages installed (omnisong/odesli, omnisong/itunes) registered, the catalogues built from configuration and asked in that order by the one CatalogInterface that is autowired, the Embedder with the site's theme, and the Twig functions:

omnisong: catalogs: odesli: { factory: odesli, options: { api_key: '%env(default::ODESLI_API_KEY)%', country: 'DE' } } itunes: { factory: itunes, options: { country: 'de' } } player: theme: light country: ~

public function __construct(CatalogInterface $catalog, EmbedderInterface $embedder) }
public function __construct(CatalogInterface $itunes) }   // one catalogue, by its name

An application's own factories (a CatalogFactoryInterface) are registered too, autoconfigured.

OmnisongBundle::configure()

public function configure(DefinitionConfigurator $definition): void

OmnisongBundle::loadExtension()

public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void

OmnisongBundle::aggregate()

public static function aggregate(Registry $registry): Catalog

Every configured catalogue, in the configured order, as one.

Omnisong\Bridge\Twig

OmnisongExtension class

final class OmnisongExtension extends AbstractExtension OmnisongExtension.php:20

The players and the platforms' names in a template:

{{ omnisong_embed(release.links.get(platform)) }} {{ omnisong_embed('https://open.spotify.com/album/...', {theme: 'dark', compact: true}) }} {{ omnisong_platform('apple_music').label }} {{ 'apple_music'|omnisong_platform_label }}

OmnisongExtension::__construct()

public function __construct(readonly EmbedderInterface $embedder, readonly ?EmbedOptions $defaults = null)

OmnisongExtension::getFunctions()

public function getFunctions(): array

OmnisongExtension::getFilters()

public function getFilters(): array

OmnisongExtension::embed()

public function embed(PlatformLink|string|null $linkOrUrl, array $options = []): ?string

The iframe that plays a link, or null when its platform has none.

$options

over the configured defaults

OmnisongExtension::platform()

public function platform(?string $value): ?Platform

OmnisongExtension::label()

public function label(Platform|string|null $value): string

"apple_music" (or the Platform itself) as "Apple Music"; what is not a platform stays as it is.

Omnisong\Catalog

Catalog class

final class Catalog implements CatalogInterface Catalog.php:20

Every configured catalogue asked in turn, their answers merged: Odesli gives the links, iTunes the tracks and their previews, and the label the site knows goes first. What one catalogue cannot do the next does; a catalogue that is down is skipped, and remembered as skipped so the caller does not cache a half answer (see $incomplete).

public array $incomplete = []

Catalog::__construct()

public function __construct(iterable $catalogs)
$catalogs

in the order they are asked

Catalog::getName()

public function getName(): string

Catalog::names()

public function names(): array
public function links(Reference $reference, ?Label $label = null): PlatformLinks

Catalog::release()

public function release(Reference $reference, ?Label $label = null): ?Release

Catalog::releases()

public function releases(string $artist, int $limit = 50, ?string $country = null): array

CatalogFactory class

abstract class CatalogFactory implements CatalogFactoryInterface CatalogFactory.php:14

The Omnibus way, at its simplest: a catalogue's factory fills a Config - its name ("omnisong.factory_name"), the options it needs ("omnisong.required_options") and their defaults - then builds the catalogue from it, on the application's HTTP client when one is given.

CatalogFactory::__construct()

public function __construct(protected readonly ?HttpClientInterface $http = null)

CatalogFactory::getName()

public function getName(): string

CatalogFactory::create()

public function create(array $options = []): CatalogInterface

CatalogFactory::createConfig()

public function createConfig(array $options = []): Config

CatalogFactoryInterface interface

interface CatalogFactoryInterface CatalogFactoryInterface.php:6

Builds a catalogue from its options (a key, a country...).

CatalogFactoryInterface::getName()

public function getName(): string

The name catalogues are configured with: "odesli", "itunes".

..

CatalogFactoryInterface::create()

public function create(array $options = []): CatalogInterface

CatalogInterface interface

interface CatalogInterface CatalogInterface.php:15

A service that knows recordings: where they are (the links), what they are (a release with its tracks and previews), what an artist put out.

A catalogue answers what it can and throws NotSupportedException for the rest; the aggregator (Catalog) asks the next one.

CatalogInterface::getName()

public function getName(): string

The name it is configured as: "odesli", "itunes".

..

public function links(Reference $reference): PlatformLinks

The same recording on every platform this catalogue knows.

CatalogInterface::release()

public function release(Reference $reference): ?Release

The release (its tracks, previews, cover, label...) the reference names, or null when unknown.

CatalogInterface::releases()

public function releases(string $artist, int $limit = 50, ?string $country = null): array

What an artist put out, newest first.

Omnisong\Exception

InvalidConfigException class

final class InvalidConfigException extends LogicException implements OmnisongException InvalidConfigException.php:6

A catalogue misconfigured: a key missing, an unknown factory.

InvalidReferenceException class

final class InvalidReferenceException extends InvalidArgumentException implements OmnisongException InvalidReferenceException.php:6

A value Reference::parse() cannot read: neither a URL, a UPC/EAN nor an ISRC.

NotSupportedException class

final class NotSupportedException extends LogicException implements OmnisongException NotSupportedException.php:8

The catalogue does not read that kind of reference, or does not do that at all.

NotSupportedException::reference()

public static function reference(string $catalog, Reference $reference): self

NotSupportedException::operation()

public static function operation(string $catalog, string $operation): self

OmnisongException interface

interface OmnisongException extends Throwable OmnisongException.php:6

Every exception Omnisong throws.

ProviderException class

class ProviderException extends RuntimeException implements OmnisongException ProviderException.php:6

The catalogue's service answered with an error.

public readonly string $catalog
public readonly ?int $status

ProviderException::__construct()

public function __construct(public readonly string $catalog, string $message, public readonly ?int $status = null, ?\Throwable $previous = null)

RateLimitedException class

final class RateLimitedException extends UnavailableException RateLimitedException.php:6

The service asks to slow down (Odesli: 10 requests a minute without a key).

public readonly ?int $retryAfter

RateLimitedException::__construct()

public function __construct(string $catalog, public readonly ?int $retryAfter = null, ?\Throwable $previous = null)

UnavailableException class

class UnavailableException extends ProviderException UnavailableException.php:9

The service could not be reached, or is down: never "not found". A caller that caches an answer must not cache this one.

Omnisong\Http

Redaction class

final class Redaction Redaction.php:22

What a failed call may carry of its credentials, taken out before the failure leaves the package: an HTTP client's exception quotes the URL called (a key in its query, a password in its user part), and every exception's trace keeps the arguments of the calls under it (the request options, headers and query with the key) unless PHP runs with zend.exception_ignore_args.

copy() gives the previous exception to wrap instead of the client's own: the same class and code, its message with the key's parameters, the user part and every secret value replaced by ***, its trace without arguments, its own previous copied the same way. Properties of the client's class beyond those of \Exception are not copied (a Symfony HttpException's response, a PSR-18 exception's request: their URL holds the key). withoutArguments() takes the arguments out of the trace of the exception thrown in its place.

const MASK = '***'

Redaction::secrets()

public static function secrets(string $url, array $options = []): array

The secrets a request carries: the values of its query parameters, headers and body fields named as credentials (key, token, secret, password, signature, auth...), a bearer token, a basic password, the URL's user part.

$options

the HTTP client's options

Redaction::sensitive()

public static function sensitive(string $name): bool

Whether a parameter, header or field of this name holds a credential.

Redaction::text()

public static function text(string $text, array $secrets = []): string

A text without credentials: in every address, the user part and the parameters named as credentials masked (api_key=***); then every secret given, raw or URL-encoded, masked wherever it stands.

Redaction::copy()

public static function copy(\Throwable $failure, array $secrets = []): \Throwable

A copy of a failure to wrap in its place: its class, code, file and line, its message through text(), its trace without arguments, its previous copied the same way.

Redaction::withoutArguments()

public static function withoutArguments(\Throwable $failure): \Throwable

The failure given, the arguments out of its trace (and out of its previous ones'), as zend.exception_ignore_args would have left it.

Omnisong\Model

Artist class

final class Artist Artist.php:6

A performer as a catalogue names it, with its ids on the platforms that gave one.

public readonly string $name
public readonly array $ids

platform value => the platform's id

public readonly ?string $url
public readonly ?string $imageUrl

Artist::__construct()

public function __construct(public readonly string $name, public readonly array $ids = [], public readonly ?string $url = null, public readonly ?string $imageUrl = null)
$ids

platform value => the platform's id

Embed class

final class Embed Embed.php:8

An iframe that plays from a platform: its markup, its size, where it loads from (for a CSP).

public readonly Platform $platform
public readonly string $html
public readonly string $src
public readonly int $width
public readonly int $height

Embed::__construct()

public function __construct(public readonly Platform $platform, public readonly string $html, public readonly string $src, public readonly int $width, public readonly int $height)

Label class

final class Label Label.php:6

The label a release came out on: who to show first, and where its shop is.

public readonly string $name
public readonly ?string $url
public readonly ?string $shopUrl

Label::__construct()

public function __construct(public readonly string $name, public readonly ?string $url = null, public readonly ?string $shopUrl = null)

final class PlatformLink PlatformLink.php:8

One place the recording is: the platform, the URL, the platform's own id when known.

For LABEL and SHOP: the name to show ("ES-DUR", "Presto Music")

public function __construct(public readonly Platform $platform, public readonly string $url, public readonly ?string $id = null, public readonly ?string $title = null, public readonly ?string $country = null)
public function title(): string

final class PlatformLinks implements IteratorAggregate, Countable PlatformLinks.php:14

The links of one recording, one per platform, in the order a site shows them: the label first, then the shops, then the streamers (Platform::rank()).

Immutable: merge() and with() give a new one.

public function __construct(iterable $links = [])
public static function none(): self
public function get(Platform $platform): ?PlatformLink
public function has(Platform $platform): bool
public function first(): ?PlatformLink

The first one, the label's when there is one.

public function with(PlatformLink $link): self
public function withLabel(Label $label): self
public function merge(?self $other): self

Ours first: a platform both have keeps this one's link.

public function all(): array
public function embeddable(): array
Returns

those the Embedder can play

public function toArray(): array
Returns

platform value => URL

public static function fromArray(array $urls, ?string $labelName = null): self
$urls

platform value => URL (unknown values become OTHER... no: skipped)

public function getIterator(): \Traversable
public function count(): int

Reference class

final class Reference Reference.php:13

What a catalogue is asked about: a URL on any platform, an ISRC (a recording), a UPC/EAN (a release), or a platform's own id. One of them is enough; a catalogue that cannot read the kind given says so (NotSupportedException).

const SONG = 'song'
const ALBUM = 'album'

Reference::url()

public static function url(string $url, ?string $country = null): self

Reference::isrc()

public static function isrc(string $isrc, ?string $country = null): self

Reference::upc()

public static function upc(string $upc, ?string $country = null): self

Reference::id()

public static function id(Platform $platform, string $id, string $type = self::ALBUM, ?string $country = null): self

Reference::parse()

public static function parse(string $value, ?string $country = null): self

A loose string: a URL, 12-14 digits (UPC/EAN), 12 alphanumerics (ISRC).

Reference::withCountry()

public function withCountry(?string $country): self

Reference::__toString()

public function __toString(): string

Release class

final class Release Release.php:10

An album, a single, an EP as the catalogues know it: its title, its artist, its label, the UPC that names it, its cover, its tracks, and the links to every platform (the label's first).

const ALBUM = 'album'
const SINGLE = 'single'
const EP = 'ep'
public readonly string $title
public readonly ?string $artist
public readonly ?Label $label
public readonly ?string $upc
public readonly ?\DateTimeImmutable $releasedAt
public readonly ?string $coverUrl
public readonly string $type
public readonly array $tracks
public readonly ?string $genre
public readonly ?int $trackCount
public readonly array $ids

platform value => the platform's id

Release::__construct()

public function __construct(public readonly string $title, public readonly ?string $artist = null, public readonly ?Label $label = null, public readonly ?string $upc = null, public readonly ?\DateTimeImmutable $releasedAt = null, public readonly ?string $coverUrl = null, public readonly string $type = self::ALBUM, public readonly array $tracks = [], public readonly ?PlatformLinks $links = null, public readonly ?string $genre = null, public readonly ?int $trackCount = null, public readonly array $ids = [], public readonly ?string $copyright = null)
$ids

platform value => the platform's id

public function withLinks(PlatformLinks $links): self

Release::withTracks()

public function withTracks(array $tracks): self

Release::withLabel()

public function withLabel(?Label $label): self

Release::merge()

public function merge(?self $other): self

What another catalogue knew that this one did not: each null filled, tracks and links merged.

Source class

final class Source Source.php:6

Something an <audio> element can play: a file of the site's, or a catalogue's preview.

const FILE = 'file'
const PREVIEW = 'preview'
public readonly string $url
public readonly string $kind
public readonly ?string $mime
public readonly ?int $duration

seconds, when known

Source::__construct()

public function __construct(public readonly string $url, public readonly string $kind = self::FILE, public readonly ?string $mime = null, public readonly ?int $duration = null)

Track class

final class Track Track.php:10

One recording of a release: its place, its title, who plays, the ISRC that names it everywhere, and the preview a catalogue offers (iTunes: 30 seconds, licensed for that use).

public readonly string $title
public readonly ?int $position
public readonly ?int $disc
public readonly ?int $duration

seconds

public readonly ?string $isrc
public readonly ?string $previewUrl
public readonly ?string $artist
public readonly ?string $composer
public readonly array $ids

platform value => the platform's id

public readonly ?string $url

Track::__construct()

public function __construct(public readonly string $title, public readonly ?int $position = null, public readonly ?int $disc = null, public readonly ?int $duration = null, public readonly ?string $isrc = null, public readonly ?string $previewUrl = null, public readonly ?string $artist = null, public readonly ?string $composer = null, public readonly array $ids = [], public readonly ?string $url = null)
$ids

platform value => the platform's id

Track::withPreview()

public function withPreview(?string $previewUrl): self

Omnisong\Player

EmbedOptions class

final class EmbedOptions EmbedOptions.php:6

How an embed should look: the theme of the page it sits in, compact or full, autoplay (only after a click).

const LIGHT = 'light'
const DARK = 'dark'
public readonly string $theme
public readonly bool $compact
public readonly bool $autoplay
public readonly ?string $country

ISO 3166-1 alpha-2: the store Apple Music opens (its URLs carry one; this overrides)

public readonly ?string $color

A hex colour without '#', for the players that take one (SoundCloud)

EmbedOptions::__construct()

public function __construct(public readonly string $theme = self::LIGHT, public readonly bool $compact = false, public readonly bool $autoplay = false, public readonly ?string $country = null, public readonly ?string $color = null)

EmbedOptions::dark()

public function dark(): bool

Embedder class

final class Embedder implements EmbedderInterface Embedder.php:16

The platforms' own players, from their public embed URLs - no key, no SDK: Spotify (open.spotify.com/embed: albums, tracks, playlists, artists), Apple Music (embed.music.apple.com), Deezer (widget.deezer.com), YouTube (youtube-nocookie.com), SoundCloud (w.soundcloud.com). Every iframe is lazy and sandboxed as the platform requires; a site loads it on a click, never with the page.

Embedder::__construct()

public function __construct(readonly ?EmbedOptions $defaults = null)
$defaults

how an embed looks when embed() is not told (the site's theme)

Embedder::supports()

public function supports(Platform $platform): bool

Embedder::embed()

public function embed(PlatformLink $link, ?EmbedOptions $options = null): ?Embed

EmbedderInterface interface

interface EmbedderInterface EmbedderInterface.php:10

Turns a platform link into the iframe that plays it - without any key, for the platforms that allow it.

EmbedderInterface::supports()

public function supports(Platform $platform): bool

EmbedderInterface::embed()

public function embed(PlatformLink $link, ?EmbedOptions $options = null): ?Embed

null when the URL is not one this platform embeds (an artist page, a search...).