Clappr is an extensible, open-source, plugin-oriented, HTML5-first media player for web applications. It was designed around these main components:
Keep extensibility open: You can create an entire plugin in a different repository, you can disable it, you can create a new playback that is able to work with the old media control and existent plugins.
Use mainly events to communicate with components: which makes your program less coupling in your plugin level... you don't need to call a function, you can listen to events and trigger events.
Have a minimal footprint: You can add the plugins you need, for instance you don't need to load Chromecast when you don't need it.
graph TD
subgraph "Media Formats"
MP4["<mp4>"]
HLS["<hls>"]
DASH["<dash>"]
end
subgraph "Core Components"
PLAYBACK["playback"]
CONTAINER["container"]
CORE["core"]
end
subgraph "Media Control"
MEDIACONTROL["media control"]
end
MP4 --> PLAYBACK
HLS --> PLAYBACK
DASH --> PLAYBACK
PLAYBACK --> CONTAINER
CONTAINER --> CORE
CORE --> MEDIACONTROL
classDiagram
direction LR
class Player
class BaseObject
class Playback
class UIObject
class Container
class ContainerPlugin
class UIContainerPlugin
class CorePlugin
class UICorePlugin
class Core
Player <|-- BaseObject : Extends
UIObject <|-- BaseObject : Extends
Container <|-- UIObject : Extends
Playback <|-- UIObject : Extends
Core <|-- UIObject : Extends
CorePlugin <|-- BaseObject : Extends
ContainerPlugin <|-- BaseObject : Extends
UICorePlugin <|-- UIObject : Extends
UIContainerPlugin <|-- UIObject : Extends
Player "1" *-- "1" Core : composition
Core "1" *-- "0..n" Container : composition
Core --> "0..1" Container : active
Container "1" *-- "0..1" Playback : composition
Core "1" *-- "0..n" CorePlugin : composition
Core "1" *-- "0..n" UICorePlugin : composition
Container "1" *-- "0..n" ContainerPlugin : composition
Container "1" *-- "0..n" UIContainerPlugin : composition
classDiagram
direction LR
class Player {
+Core core
}
class Core {
+Container[] containers
+Container active
}
class Container {
+Playback playback
}
class Playback {
+play()
+pause()
+stop()
}
Player "1" *-- "1" Core : composition
Core "1" *-- "0..n" Container : composition
Core --> "0..1" Container : active
Container "1" *-- "0..1" Playback : composition
classDiagram
direction LR
class BaseObject {
+ uniqueId: String
+ options: Object
+ on(name, callback, context)
+ once(name, callback, context)
+ off(name, callback, context)
+ trigger(name)
+ listenTo(obj, name, callback)
+ stopListening(obj, name, callback)
}
class UIObject {
+ cid: String
+ el: HTMLElement
+ $el: ZeptoCollection
+ tagName: String
+ events: Object
+ attributes: Object
+ render()
+ destroy()
+ setElement(element, delegate)
+ delegateEvents(events)
+ undelegateEvents()
+ resize(options)
+ onResize()
}
class CorePlugin {
+ core: Core
+ enabled: Boolean
+ bindEvents()
+ enable()
+ disable()
+ getExternalInterface()
+ destroy()
}
class ContainerPlugin {
+ container: Container
+ enabled: Boolean
+ bindEvents()
+ enable()
+ disable()
+ destroy()
}
class UICorePlugin {
+ core: Core
+ enabled: Boolean
+ bindEvents()
+ enable()
+ disable()
+ render()
+ getExternalInterface()
}
class UIContainerPlugin {
+ container: Container
+ enabled: Boolean
+ bindEvents()
+ enable()
+ disable()
}
BaseObject <|-- CorePlugin : extends
BaseObject <|-- ContainerPlugin : extends
BaseObject <|-- UIObject : extends
UIObject <|-- UICorePlugin : extends
UIObject <|-- UIContainerPlugin : extends
sequenceDiagram
participant Player
participant CoreFactory
participant Core
participant CorePlugin
participant ContainerFactory
participant Container
participant ContainerPlugin
participant Playback
activate Player
Note over Player: new Player(options)
Player->>CoreFactory: new CoreFactory(player)
activate CoreFactory
Note over Player: attachTo(element) [if parentId/parent provided]
Player->>CoreFactory: create()
activate Core
CoreFactory->>Core: new Core(options)
CoreFactory->>CoreFactory: addCorePlugins()
activate CorePlugin
CoreFactory->>CorePlugin: new Plugin(core)
CoreFactory->>Core: addPlugin(plugin)
deactivate CorePlugin
CoreFactory->>Core: createContainers(options)
activate ContainerFactory
Core->>ContainerFactory: new ContainerFactory(options, loader, i18n, playerError)
ContainerFactory->>ContainerFactory: createContainers()
loop For each source
activate Container
ContainerFactory->>Container: new Container(source, options)
ContainerFactory->>ContainerFactory: findPlaybackPlugin(source, mimeType)
activate Playback
ContainerFactory->>Playback: canPlay(source, mimeType)
Container->>Playback: new Playback(source, options)
activate ContainerPlugin
Container->>ContainerPlugin: new Plugin(container)
Container->>Container: addPlugin(plugin)
deactivate ContainerPlugin
Playback-->>Container: ready
deactivate Playback
Container-->>ContainerFactory: ready
deactivate Container
end
ContainerFactory-->>Core: containers ready
deactivate ContainerFactory
Core-->>CoreFactory: ready
deactivate Core
CoreFactory-->>Player: core ready
deactivate CoreFactory
Player-->>Player: ready
deactivate Player
