Directive for declarative work with HTML5 video and audio
currentTime: 0
volume: 1
paused: true
<video
controls
tuiMedia
width="320"
class="video"
[(currentTime)]="currentTime"
[(paused)]="paused"
[(volume)]="volume"
>
<source
*tuiHighDpi
src="assets/media/bbb_dpi.ogv"
type="video/ogg"
/>
<source
src="assets/media/bbb.mp4"
type="video/mp4"
/>
</video>
<p>currentTime: {{ currentTime }}</p>
<p>volume: {{ volume }}</p>
<p>paused: {{ paused }}</p>
:host {
display: block;
}
.video {
float: left;
margin-inline-end: 1.5rem;
// Safari 15+
@supports (float: inline-start) {
float: inline-start;
}
}
<div class="player">
<video
#video
tuiMedia
width="320"
class="video"
[(currentTime)]="currentTime"
[(paused)]="paused"
(click)="toggleState()"
>
<source
src="assets/media/bbb.mp4"
type="video/mp4"
/>
</video>
<div
tuiTheme="dark"
class="controls"
>
<button
appearance="secondary-grayscale"
size="s"
title="Play/Pause"
tuiIconButton
type="button"
[iconStart]="icon"
[style.border-radius.%]="100"
(click)="toggleState()"
></button>
<input
step="any"
tuiSlider
type="range"
class="slider"
[max]="video.duration"
[(ngModel)]="currentTime"
/>
<div class="time">
<time [attr.datetime]="getTime(currentTime)">
{{ getTime(currentTime) }}
</time>
/
<time [attr.datetime]="getTime(video.duration)">
{{ getTime(video.duration) }}
</time>
</div>
</div>
</div>
:host {
display: block;
}
.video {
display: block;
}
.player {
position: relative;
inline-size: 20rem;
}
.controls {
position: absolute;
display: flex;
inset-block-end: 0;
inline-size: 100%;
align-items: center;
padding: 0.75rem 0.75rem 0.5rem;
box-sizing: border-box;
color: var(--tui-text-primary);
background: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.56));
}
.slider {
flex: 1;
margin-inline-start: 0.75rem;
}
.time {
flex-shrink: 0;
margin-inline-start: 0.75rem;
font-size: 0.8125rem;
}
<div class="tui-player">
<audio
#audio
src="assets/media/strays.mp3"
tuiMedia
[(currentTime)]="currentTime"
[(paused)]="paused"
></audio>
<button
appearance="flat"
title="Play/Pause"
tuiIconButton
type="button"
[iconStart]="icon"
[style.border-radius.%]="100"
(click)="toggleState()"
></button>
<div>
<a
href="https://waterplea.bandcamp.com/"
tuiLink
>
Waterplea
</a>
— Strays
<input
step="any"
tuiSlider
type="range"
class="slider"
[max]="audio.duration"
[(ngModel)]="currentTime"
/>
</div>
</div>
.tui-player {
display: flex;
inline-size: 20rem;
border-radius: 6.25rem;
background: var(--tui-background-neutral-1);
--tui-background-accent-1: var(--tui-text-action);
--tui-background-accent-1-hover: var(--tui-text-action-hover);
--tui-background-accent-1-pressed: var(--tui-text-action-hover);
& > div {
flex: 1;
margin: 0.375rem 1.75rem 0 0.375rem;
}
}