Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project Scaffolding and mux-video initial implementation #4

Merged
merged 17 commits into from
Aug 17, 2021

Conversation

cjpillsbury
Copy link
Contributor

  • Adds initial scaffolding for the monorepo/project (issue templates, gitignore, package.json, workspace defs, other env stuff)
  • Adds initial impl of the mux-video package.

Copy link
Contributor

@dylanjha dylanjha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a really good start, the last missing bit (which we talked about over DM) is a prop for the application to pass in Mux Data metadata fields.

## The current behavior


## The expected behavior
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a great template and after this is merged we should link to this and the other templates from our "Open Source at Mux" notion doc as good examples


const env_key = this.getAttribute(Attributes.ENV_KEY);

if (Hls.isSupported()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to make sure we're intentional about using Hls.js in native Mac OS Safari.

I typically lean the other way on this and say "on native Mac Safari just use Safari's Hls"

Pros of using Hls.js in Mac Safari:

  • Mux Data gets request-level metrics

Cons

  • I've seen it have issues before

@cjpillsbury thoughts based on your experience? Maybe we can dig up some Mux Data ™️ to inform this decision

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah let's audit/followup re: "Mux Data". I always prefer to use Hls.js for consistency/control when/where possible, but can see arguments for deferring to native safari support.

packages/mux-video/src/index.ts Show resolved Hide resolved
player_name: "mux-video", // any arbitrary string you want to use to identify this player
// Should this be the initialization of *THIS* player (instance) or the page?
player_init_time: this.__muxPlayerInitTime, // ex: 1451606400000
// ...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple other metadata fields we can automatically set:

  • video_duration (The length of the video in milliseconds) -- if the video is a VOD
  • video_stream_type (The type of video stream (e.g: 'live' or 'on-demand'))
  • player_version (read this value from the package.json?)
  • video_id (Your internal ID for the video) -- we can set this as the Mux playback_id

Particularly for video_id, we wouldn't want to over-ride a value that the user passes in. This might get a little tricky based on the order of when things are initialized and how/when the user sets Mux Data metadata props.

Maybe we can also have a debug attribute that will flip on debug mode for mux-video (& enable the debug flag mux.monitor

packages/mux-video/examples/index.html Outdated Show resolved Hide resolved
@dylanjha
Copy link
Contributor

First Round QA Pass

Default styles:

  • Right now the default styles don't mirror what I would get with a "normal" HTML5 <video> element. These are the styles that get applied
:host {
  position: relative;
  width: 300px;
  height: 150px;
}

video {
  position: absolute;
  width: 100%;
  height: 100%;
}

As a result, I end up with a tiny postage stamp sized video player on the page, which is quite different than if I had just a regular <video> element and wired up HLS.js myself.

Ideally (and I could be persuaded off of this) I think the experience we want is someone could:

  1. remove their <video> element + Hls.js stuff
  2. drop in <mux-video> (if their video element had a CSS class selector like .video-player on their video element they could put that class on this element and end result would look the same)

I think by removing the styles above and keeping the rest we're able to achieve that.

Usage with query params

  • Mux supports a number of query params on stream.mux.com URLs (the most common being token= for signed URLs
  • When using the playback-id shorthand, we'll need to support query params so that playback-id="abc123?token=xyz789" gets expanded to a src that looks like https://stream.mux.com/abc123.m3u8?token=xyz789

Importing as a dep on other projects

I added a yarn build command -- does this look right?

diff --git a/packages/mux-video/package.json b/packages/mux-video/package.json
index 2c85a0e..2d6536c 100644
--- a/packages/mux-video/package.json
+++ b/packages/mux-video/package.json
@@ -12,7 +12,8 @@
   "license": "MIT",
   "private": true,
   "scripts": {
-    "dev": "snowpack dev --config snowpack.dev.config.js"
+    "dev": "snowpack dev --config snowpack.dev.config.js",
+    "build": "snowpack build --config snowpack.prod.config.js"
   },
   "dependencies": {
     "custom-video-element": "^0.0.2",
diff --git a/packages/mux-video/snowpack.prod.config.js b/packages/mux-video/snowpack.prod.config.js
index c57a372..b82e532 100644
--- a/packages/mux-video/snowpack.prod.config.js
+++ b/packages/mux-video/snowpack.prod.config.js
@@ -5,7 +5,7 @@
 module.exports = {
   extends: './snowpack.common.config.js',
   mount: {
-    'src/js': { url: '/' },
+    'src': { url: '/' },
   },
   optimize: {
     bundle: false,

Next, when I imported @mux/mux-video into a Next.js application I got this error:

nextjs-boo_2021-08-16_23-05-29

Looks like maybe ES modules are causing a problem with SSR? I was able to work around this by opting out of SSR, and then everything was working although I am seeing a couple errors:

  • Typescript: 7016: Could not find a declaration file for module '@mux/mux-video'.
  • Typescript: 2339: Property 'mux-video' does not exist on type 'JSX.IntrinsicElements'.

Other Notes

// Should this be the initialization of THIS player (instance) or the page?

I saw this comment related to player_init_time the answer is: THIS player (instance), so you have this correct

"Some metadata values may not be overridable at this time. Make sure you set all metadata to override before setting the src."

I see the issue here, for the most part this actually doesn't cause any issues. The only time it would is if the user sets a metadata field that we're already going to automatically populate like one of these in the comment above

That should actually be pretty rare. It seems like we're recommending a workflow like this:

<mux-video env-key="mux-env-key"></mux-video>

<script>
  const muxVideo = document.querySelector('mux-video')
  muxVideo.metadata = { video_title: '', video_series: '' };
  muxVideo.setAttribute('playback-id', 'my-playback-id');
</script>

^ that feels a little bit jank, maybe we can do something like this and allow the user to pass in specific metadata overrides as attributes:

<mux-video
  env-key="mux-env-key"
  playback-id="my-playback-id"
  metadata-video-id="arbitrary-video-id"
 ></mux-video>

^ metadata-video-id is a field that mux-video will automatically populate with the playback-id at initialization time, but if the user passes it in via an attribute then we'll let them override it

Or maybe we can expose the most common subset of the Mux Data metadata fields with metadata-* attributes?

The thing I'm getting at is that it's nice if we can lean on HTML here as much as possible and having that work for the 90% of use cases, and then allow folks to drop down into JS land for the other 10% of advanced cases.

@cjpillsbury
Copy link
Contributor Author

Will be creating followup issues for various talking points/issues @dylanjha identified in his feedback

@cjpillsbury cjpillsbury merged commit bdf0559 into muxinc:main Aug 17, 2021
Copy link
Contributor

@heff heff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff!

return this.__hls;
}

get mux(): Readonly<typeof mux> | undefined {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should really rename this getter. Maybe to muxData .

this.__muxPlayerInitTime = Date.now();
}

get hls() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're on the same page here where we should probably expose this now, but aim to deprecated it when we can cover most things people are doing with it. Otherwise we lock ourselves into HLS.js.

console.info(
"Some metadata values may not be overridable at this time. Make sure you set all metadata to override before setting the src."
);
this.mux.emit("hb", this.__metadata);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this actually work if you call it anywhere mid playback? i.e. will the title change? Feels like this might have a weird impact on real-time data.

return this.__metadata;
}

set metadata(val: Readonly<Metadata> | undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels pretty specifically deigned for Mux Data, whereas "metadata" might be used in multiple ways. e.g. a title might be used in the UI. I don't have a better answer but feels worth calling out.

I did have one related idea of allowing meta data elements inside the media element.

<media-container>
  <video>
    <media-meta-title>Big Buck Bunny</media-meta-title>
  </video>
</media-container

Food for thought. No immediate change requested here.

}

disconnectedCallback() {
this.unload();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does <video> reset its loaded state when you remove it from/add it to the dom?

/** @TODO Refactor once using `globalThis` polyfills */
if (!window.customElements.get("mux-video")) {
window.customElements.define("mux-video", MuxVideoElement);
/** @TODO consider externalizing this (breaks standard modularity) */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also a nice to have, not a must have.

const hadSrc = !!oldValue;
const hasSrc = !!newValue;
if (!hadSrc && hasSrc) {
this.load();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<video> doesn't automatically load() when you change the src=. I'm not sure we want to divert here.

}
}

// NOTE: This was carried over from hls-video-element. Is it needed for an edge case?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can delete it. It was half progress towards support the preload= API.

}

unload() {
// NOTE: I believe we cannot reliably "recycle" hls player instances, but should confirm at least for optimization reasons.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I tried and HLS was not happy, but worth confirming.

}
}

unload() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably fine and helpful to add this method, but with <video> you'd set an empty src and call load(), so we should make sure that also works. For example a playlist function might expect that.

clearlyTHUYDOAN added a commit to clearlyTHUYDOAN/elements that referenced this pull request May 10, 2022
[WIP] Bar progress UI plus some bells
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants