Ionic 4: Autoplay videos on scroll

Often, achieving Instagram or Facebook type experience is more difficult than it sounds in Ionic. To bridge that gap, I’m going to show you how to automatically play and pause videos in your app as your user scrolls.

Jordan Benge
Jun 14 · 9 min read
Photo by Hermes Rivera on Unsplash

Let’s get started

Edit Config.xml

...
<preference name="ScrollEnabled" value="false" />
<preference name="android-minSdkVersion" value="19" />
<preference name="BackupWebStorage" value="none" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="FadeSplashScreenDuration" value="300" />
<preference name="SplashShowOnlyFirstTime" value="false" />
<preference name="SplashScreen" value="screen" />
<preference name="SplashScreenDelay" value="3000" />
<preference name=”AllowInlineMediaPlayback” value=”true” />
...

Package — ng-in-viewport to the rescue!

Let’s generate some code!

Imports — App.module.ts

import { InViewportDirective } from 'ng-in-viewport';
...
@NgModule({
declarations: [
InViewportDirective,
...
],
...
exports: [
...
InViewportDirective,
],

Lets get down to business…to defeat…the videos!

Class — video.ts

export interface VideoInterface {
src?: string;
id: string;
}

export class Video implements VideoInterface {

public src: string;
public id: string;

constructor(id: string) {
this.id = id;
this.src = 'https://ia800501.us.archive.org/10/items/BigBuckBunny_310/big_buck_bunny_640_512kb.mp4';
}
}

Component — inline-video.component.ts

import { InViewportMetadata } from 'ng-in-viewport';
import { Video } from '../../../classes/video';
public video: Video = new Video('someUniqueId');

Function — changeVideoAudio(id: string)

public changeVideoAudio(id: string) {
let vid: any = document.getElementById('media-' + id);
vid.muted = !vid.muted;
}

Function — onIntersection($event)

onIntersection($event) {
const { [InViewportMetadata]: { entry }, target } = $event;
const ratio = entry.intersectionRatio;
const vid = target;

ratio >= 0.65 ? vid.play() : vid.pause();
}
const ratio = entry.intersectionRatio;
const vid = target;
ratio >= 0.65 ? vid.play() : vid.pause();

Component — inline-video.component.html

<div tappable (tap)="changeVideoAudio(video?.id)">
...
</div>
<div tappable (tap)="changeVideoAudio(video?.id)">
<video
inViewport
[inViewportOptions]="{ threshold: [0, 0.65], partial: true }"
(inViewportAction)="onIntersection($event)"
playsinline loop
[muted]="'muted'" preload="auto" muted="muted"
[poster]="video?.src"
[id]="'media-' + video?.id" class="video-media">
<source [src]="video.src" type="video/mp4" src="">
</video>
</div>
[inViewportOptions]="{ threshold: [0, 0.65], partial: true }"
(inViewportAction)="onIntersection($event)"
[muted]="'muted'" preload="auto" muted="muted"
[id]="'media-' + video?.id" class="video-media">
<source [src]="video.src" type="video/mp4">
example demo

That’s it!


Questions?

If you enjoyed this story, please click the 👏 button and share to help others find it! Feel free to leave a comment below if you need any help.

Jordan Benge

Written by

My name is Jordan Benge, I’m a freelance developer, and sometimes like to write helpful articles on Medium for the dazed and confused developers — like myself.