Skip to content

Commit 0c676c2

Browse files
luwesismapin22cjpillsburyN1KnightronalduQualabs
authored
feat: news player (#1115)
This PR builds on top of ismapin22#12 Changes - Removed the `dist` outputs - Added a GH action to build and push the output to a new branch called `release-news-player` whenever something is pushed to the `main-news-player` branch - Fixed some build, lint issues --------- Co-authored-by: Ismael Pintos <ismaelp@qualabs.com> Co-authored-by: Christian Pillsbury <cjpillsbury@gmail.com> Co-authored-by: Ismael Pintos <126787891+ismapin22@users.noreply.github.com> Co-authored-by: Nicolas Caballero <nicolascaballero.v@gmail.com> Co-authored-by: ronalduQualabs <ronaldu@qualabs.com>
1 parent 9ec91c8 commit 0c676c2

36 files changed

+3826
-103
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Deployment of News player components
2+
3+
concurrency: production
4+
5+
on:
6+
push:
7+
branches:
8+
- main-news-player
9+
10+
jobs:
11+
release:
12+
runs-on: ubuntu-latest
13+
environment: production
14+
permissions:
15+
contents: write
16+
pull-requests: write
17+
id-token: write
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
# these if statements ensure that a publication only occurs when
22+
# a new release is created:
23+
with:
24+
fetch-depth: 0 # Fetch all history for all tags and branches
25+
- name: read node version from the .nvmrc file
26+
run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc)
27+
shell: bash
28+
id: nvmrc
29+
- uses: actions/setup-node@v4
30+
with:
31+
node-version: ${{steps.nvmrc.outputs.NODE_VERSION}}
32+
# this line is required for the setup-node action to be able to run the npm publish below.
33+
registry-url: 'https://registry.npmjs.org'
34+
35+
- name: Install
36+
run: npm ci
37+
- name: Clean
38+
run: npm run clean
39+
# - name: Test
40+
# run: npm test
41+
- name: Clean
42+
run: npm run clean
43+
- name: Build
44+
run: npm run build:packages
45+
46+
- name: Append !dist to gitignore
47+
run: echo '!dist' >> .gitignore
48+
- name: Commit changes to git
49+
run: git commit -am "Update .gitignore to include !dist"
50+
- name: Force push to release-news-player
51+
run: git push origin release-news-player --force

examples/nextjs-with-typescript/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"@mux/mux-uploader-react": ">=1.0.0-beta.0",
2020
"@mux/mux-video": ">=0.3.0",
2121
"@mux/mux-video-react": ">=0.3.0",
22+
"media-chrome": "^4.9.0",
2223
"next": "^14.2.2",
2324
"react": "^18.2.0",
2425
"react-dom": "^18.2.0",
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
'use client';
2+
import Link from "next/link";
3+
import Head from 'next/head';
4+
import { useRef, useState, useEffect } from "react";
5+
import '@mux/mux-video-ads';
6+
import MuxPlayer from "@mux/mux-player-react";
7+
import NewsTheme from "@mux/mux-player-react/themes/news-theme";
8+
9+
const INITIAL_AUTOPLAY = false;
10+
const INITIAL_MUTED = false;
11+
12+
function MuxPlayerAdsPage() {
13+
const mediaElRef = useRef(null);
14+
const [autoplay, setAutoplay] = useState<"muted" | boolean>(INITIAL_AUTOPLAY);
15+
const [muted, setMuted] = useState(INITIAL_MUTED);
16+
const [paused, setPaused] = useState<boolean | undefined>(true);
17+
18+
const [sdkLoaded, setSdkLoaded] = useState(false);
19+
20+
useEffect(() => {
21+
// Dynamically load the IMA SDK
22+
const loadImaSdk = () => {
23+
const script = document.createElement("script");
24+
script.src = "https://imasdk.googleapis.com/js/sdkloader/ima3.js";
25+
script.async = true;
26+
script.onload = () => {
27+
setSdkLoaded(true); // Mark SDK as loaded
28+
console.log("Google IMA SDK loaded");
29+
};
30+
script.onerror = () => {
31+
console.warn("Google IMA SDK failed to load. Likely blocked by ad blocker.");
32+
setSdkLoaded(true);
33+
};
34+
document.head.appendChild(script);
35+
};
36+
37+
if (!window.google || !window.google.ima) {
38+
loadImaSdk();
39+
} else {
40+
setSdkLoaded(true);
41+
}
42+
43+
return () => {
44+
// Cleanup by removing the script
45+
const scriptElement = document.querySelector('script[src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"]');
46+
if (scriptElement) {
47+
scriptElement.remove();
48+
}
49+
};
50+
}, []);
51+
52+
return (
53+
<>
54+
<Head>
55+
<title>&lt;MuxPlayer/&gt; (theme) Demo</title>
56+
</Head>
57+
<NewsTheme/>
58+
59+
{sdkLoaded && <MuxPlayer
60+
ref={mediaElRef}
61+
playbackId="ihZa7qP1zY8oyLSQW9TS602VgwQvNdyIvlk9LInEGU2s"
62+
theme="news-theme"
63+
themeProps={{ controlBarVertical: true, controlBarPlace: 'start start' }}
64+
metadata={{
65+
video_id: "video-id-12345",
66+
video_title: "Elephants Dream",
67+
viewer_user_id: "user-id-6789",
68+
}}
69+
streamType="on-demand"
70+
// envKey="mux-data-env-key"
71+
autoPlay={autoplay}
72+
muted={muted}
73+
muxVideoElement='mux-video-ads'
74+
adTagUrl='https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_preroll_skippable&sz=640x480&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator='
75+
onPlay={() => {
76+
setPaused(false);
77+
}}
78+
onPause={() => {
79+
setPaused(true);
80+
}}
81+
/>}
82+
</>
83+
);
84+
}
85+
86+
export default MuxPlayerAdsPage;

examples/nextjs-with-typescript/pages/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function HomePage() {
99
<li><Link href='/MuxPlayer?playbackId="ihZa7qP1zY8oyLSQW9TS602VgwQvNdyIvlk9LInEGU2s"' className="player">&lt;MuxPlayer&gt;</Link></li>
1010
<li><Link href="/MuxPlayerPosterSlot" className="player"><>&lt;MuxPlayer&gt;<br/>(poster slot)</></Link></li>
1111
<li><Link href="/MuxPlayerTheme" className="player"><>&lt;MuxPlayer&gt;<br/>(theme)</></Link></li>
12+
<li><Link href="/MuxPlayerAds" className="player"><>&lt;MuxPlayerAds&gt;<br />(Ads)</></Link></li>
1213
<li><Link href="/MuxPlayerCuePoints" className="player"><>&lt;MuxPlayer&gt;<br/>(CuePoints)</></Link></li>
1314
<li><Link href="/MuxPlayerCuePointsMeditate" className="player"><>&lt;MuxPlayer&gt;<br/>(CuePoints + Audio Only)</></Link></li>
1415
<li><Link href="/MuxPlayerChapters" className="player"><>&lt;MuxPlayer&gt;<br/>(Chapters)</></Link></li>
@@ -24,6 +25,8 @@ function HomePage() {
2425
<li><Link href="/mux-audio" className="audio"><>&lt;mux-audio&gt;<br/>(Web Component)</></Link></li>
2526
<li><Link href="/mux-player" className="player"><>&lt;mux-player&gt;<br/>(Web Component)</></Link></li>
2627
<li><Link href="/mux-video-react" className="video"><>&lt;MuxVideo&gt;<br/>(React Web Component)</></Link></li>
28+
<li><Link href="/mux-video-ads-react" className="video"><>&lt;MuxVideoAds&gt;<br />(React Web Component)</></Link></li>
29+
<li><Link href="/playlist-page" className="video"><>&lt;Playlist&gt;<br />(React Web Component)</></Link></li>
2730
<li><Link href="/app-router" className="react"><>App Router</></Link></li>
2831
</ul>
2932
</nav>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import Head from 'next/head';
2+
import { useRef, useState, useEffect } from "react";
3+
import MuxVideoAds from "@mux/mux-video-ads/react";
4+
import '../post-video.css'
5+
6+
const INITIAL_AUTOPLAY = false;
7+
const INITIAL_MUTED = false;
8+
9+
function MuxVideoPage() {
10+
const mediaElRef = useRef(null);
11+
const [autoplay, setAutoplay] = useState<"muted" | boolean>(INITIAL_AUTOPLAY);
12+
const [muted, setMuted] = useState(INITIAL_MUTED);
13+
const [paused, setPaused] = useState<boolean | undefined>(true);
14+
const [sdkLoaded, setSdkLoaded] = useState(false);
15+
16+
const mainVideo = {
17+
imageUrl: "https://d.newsweek.com/en/full/2616049/picture-video.jpg?w=480&h=270&q=75&f=234a33201b1c5adb080a1bec0cb4a4a0",
18+
title: "US Official Cars Seen Leaving Greenland Capital After Vance Scales Back Visit",
19+
idx: 2
20+
};
21+
22+
const relatedVideos = [
23+
{
24+
imageUrl: "https://d.newsweek.com/en/full/2614934/picture-video.jpg?w=480&h=270&q=75&f=8dbdcf86a118c0f5afb2cba69bd4af24",
25+
title: "JD Vance Announces He Will Join His Wife On Visit To Greenland",
26+
idx: 0
27+
},
28+
{
29+
imageUrl: "https://d.newsweek.com/en/full/2616059/reason-why-woman-trains-specific-arm.jpg?w=480&h=270&q=75&f=5000e727dbcc4e9e9d1ca21b1215c993",
30+
title: "Reason Why Woman Trains Specific Arm",
31+
idx: 1
32+
},
33+
{
34+
imageUrl: "https://d.newsweek.com/en/full/2616049/picture-video.jpg?w=480&h=270&q=75&f=234a33201b1c5adb080a1bec0cb4a4a0",
35+
title: "US Official Cars Seen Leaving Greenland Capital After Vance Scales Back Visit",
36+
idx: 2
37+
}
38+
];
39+
40+
useEffect(() => {
41+
// Dynamically load the IMA SDK
42+
const loadImaSdk = () => {
43+
const script = document.createElement("script");
44+
script.src = "https://imasdk.googleapis.com/js/sdkloader/ima3.js";
45+
script.async = true;
46+
script.onload = () => {
47+
setSdkLoaded(true); // Mark SDK as loaded
48+
console.log("Google IMA SDK loaded");
49+
};
50+
document.head.appendChild(script);
51+
};
52+
53+
if (!window.google || !window.google.ima) {
54+
loadImaSdk();
55+
} else {
56+
setSdkLoaded(true);
57+
}
58+
59+
return () => {
60+
// Cleanup by removing the script
61+
const scriptElement = document.querySelector('script[src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"]');
62+
if (scriptElement) {
63+
scriptElement.remove();
64+
}
65+
};
66+
}, []);
67+
68+
return (
69+
<>
70+
<Head>
71+
<title>&lt;MuxVideoAds/&gt; Demo</title>
72+
</Head>
73+
74+
{sdkLoaded && <MuxVideoAds
75+
ref={mediaElRef}
76+
playbackId="23s11nz72DsoN657h4314PjKKjsF2JG33eBQQt6B95I"
77+
controls
78+
autoplay={autoplay}
79+
muted={muted}
80+
playsInline={true}
81+
maxResolution="2160p"
82+
minResolution="540p"
83+
renditionOrder="desc"
84+
preferPlayback="mse"
85+
adTagUrl="https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_preroll_skippable&sz=640x480&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator="
86+
onPlay={() => {
87+
setPaused(false);
88+
}}
89+
onPause={() => {
90+
setPaused(true);
91+
}}
92+
onEnded={() => {
93+
94+
}}
95+
>
96+
</MuxVideoAds>}
97+
</>
98+
);
99+
}
100+
101+
export default MuxVideoPage;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import Head from 'next/head';
2+
import { MuxNewsPlayer } from "@mux/mux-player-react"
3+
import { useEffect, useState } from 'react';
4+
5+
function MuxVideoPage() {
6+
7+
const [sdkLoaded, setSdkLoaded] = useState(false);
8+
9+
useEffect(() => {
10+
// Dynamically load the IMA SDK
11+
const loadImaSdk = () => {
12+
const script = document.createElement("script");
13+
script.src = "https://imasdk.googleapis.com/js/sdkloader/ima3.js";
14+
script.async = true;
15+
script.onload = () => {
16+
setSdkLoaded(true); // Mark SDK as loaded
17+
console.log("Google IMA SDK loaded");
18+
};
19+
document.head.appendChild(script);
20+
};
21+
22+
if (!window.google || !window.google.ima) {
23+
loadImaSdk();
24+
} else {
25+
setSdkLoaded(true);
26+
}
27+
28+
return () => {
29+
// Cleanup by removing the script
30+
const scriptElement = document.querySelector('script[src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"]');
31+
if (scriptElement) {
32+
scriptElement.remove();
33+
}
34+
};
35+
}, []);
36+
37+
const relatedVideos = [
38+
{
39+
imageUrl: "https://image.mux.com/DVBhwqkhxkOiLRjUAYJS6mCBJSuC00tB4iWjJmEofJoo/thumbnail.jpg",
40+
title: "Test video title 1",
41+
playbackId: "DVBhwqkhxkOiLRjUAYJS6mCBJSuC00tB4iWjJmEofJoo",
42+
adTagUrl: "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_preroll_skippable&sz=640x480&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=",
43+
},
44+
{
45+
imageUrl: "https://image.mux.com/VcmKA6aqzIzlg3MayLJDnbF55kX00mds028Z65QxvBYaA/thumbnail.jpg",
46+
title: "Test video title 2",
47+
playbackId: "VcmKA6aqzIzlg3MayLJDnbF55kX00mds028Z65QxvBYaA",
48+
adTagUrl: "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpreonly&ciu_szs=300x250%2C728x90&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&correlator=",
49+
},
50+
{
51+
imageUrl: "https://image.mux.com/gZh02tKCI015W6k2XdYSh4srGnksYvsoT1uHsYOlv4Blo/thumbnail.jpg",
52+
title: "Test video title 3",
53+
playbackId: "gZh02tKCI015W6k2XdYSh4srGnksYvsoT1uHsYOlv4Blo",
54+
adTagUrl: "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpreonlybumper&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&correlator=",
55+
},
56+
];
57+
58+
return (
59+
<>
60+
<Head>
61+
<title>&lt;Playlist/&gt; Demo</title>
62+
</Head>
63+
64+
{sdkLoaded && <MuxNewsPlayer videoList={relatedVideos} />}
65+
66+
</>
67+
);
68+
}
69+
70+
export default MuxVideoPage;

0 commit comments

Comments
 (0)