---
title: "Live Streaming Site Notes — Part 2: Building Your Own Live Player"
description: "A hands-on walkthrough of building a frontend live-streaming player with Vue and hls.js — covering HLS protocol integration, player component encapsulation, and common gotchas."
canonical_url: "https://blog.markkulab.net/en/post/live-streaming-player"
author: "Mark Ku"
author_url: "https://blog.markkulab.net/en/author/mark-ku"
site: "Mark Ku's Tech Notes"
date_published: "2022-05-27 01:01:01 +0800"
category: "Frontend"
tags: ["直播", "streaming", "hls.js", "vue", "frontend", "video", "hls"]
language: "en"
license: "CC BY 4.0"
license_url: "https://creativecommons.org/licenses/by/4.0/"
attribution: "when reusing or quoting, credit the author and link back to the original"
---

# Live Streaming Site Notes — Part 2: Building Your Own Live Player

## Building a personal frontend live player with Vue (using hls.js)

## Foreword
In the [previous post](https://blog.markkulab.net/2021/07/20/streaming/) I covered setting up a live-streaming server on Alibaba Cloud. This time I want to talk about the frontend live player. The two most common live-streaming protocols on the web are HLS and DASH, and that's what this post focuses on.

## Tech-company rivalry
Early streaming protocols brought to mind Flash (FLV). To replace Flash and RTMP, Apple introduced the HLS streaming protocol. It's proprietary to Apple and works natively across all Apple products.

DASH is the standard MPEG developed to compete head-on with Apple's HLS. It offers lower latency and is open source.

Because there are huge numbers of iOS users globally, many sites still lean toward HLS, while several tech giants have chosen the open DASH protocol.

Companies using HLS:
foxsports, 17LIVE, Twitter, QiuHui Sports, LeiSu Sports

Companies using DASH:
Netflix, Hulu, YouTube

## What is HLS?
HTTP Live Streaming (HLS) is an HTTP-based streaming-media network protocol introduced by Apple. It is part of Apple's QuickTime X and iPhone software. The protocol works by breaking the stream into a series of small HTTP-based files and downloading them a few at a time. As the stream plays, the client can choose to download the same resource at different bitrates from many alternate sources, allowing the streaming session to adapt to different data rates. At the start of a session, the client downloads an extended M3U (m3u8) playlist file containing the metadata used to discover the available streams. (Wikipedia)

## HLS browser-compatibility
![Can I use results for HLS browser compatibility table](https://blog.markkulab.net/content/markku/posts/live-streaming-player/images/Nqhf4Uv.png)

As mentioned, HTTP Live Streaming is Apple's protocol, so it plays directly in Safari but not in Chrome and other browsers.

The Dailymotion team open-sourced **Hls.js** to solve the cross-browser compatibility problem.

## Project status
So as we've seen, you can't just play a stream directly with HTML `<video>`. Considering client compatibility and cloud support, this post adopts the HLS protocol.

## Implementation
### 1. Install hls.js
```
npm i hls.js --save
```

### 2. Using hls.js

After importing Hls.js, we call `Hls.isSupported()` to check whether the browser supports it. If it does, we can plug it straight into the video element.
```
mounted() {
	let videoSrc = "https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine-hls/hls.m3u8"

	const video = document.getElementById('live-player')
	this.player = video

	if (Hls.isSupported()) {
	const hls = new Hls()
	hls.loadSource(videoSrc)
	hls.attachMedia(video)
	} else {
	video.src = videoSrc
	}
}
```

## 3. Following the steps above, you can already play HLS live streams. But if you watch closely, when the user leaves the page the page keeps firing large requests in DevTools, eventually leading to a memory leak.

## 4. To avoid that, we have to stop and destroy the hls instance before the component is unmounted.
```
  beforeDestroy() {
      if (Object.keys(this.hls).length > 0) {
        this.hls.stopLoad()
        this.hls.destroy()
        this.hls = null
      }
  },
```

## 5. Real-world requirements are rarely that simple — users want volume controls, resolution switching, a floating mini-player when scrolling, danmaku (bullet comments), full-screen danmaku, and more.

## 6. Implementing volume control
On a mobile player you can't adjust volume through the `<video>` element — the user controls it via the device's hardware. On desktop, you can use a slider library to control the volume.

```
handleSound(e) {
this.player.volume = e / 100
},
```

## 7. Autoplay restrictions
Many browsers restrict autoplay to improve UX. To make autoplay work:
1. The video must be muted.
`<video controls muted>`
2. The user must have interacted with the site before autoplay can fire.

## 8. Floating mini-player
### 8.1 The idea is simple — while the player is playing, listen to the main scroll position. Once it scrolls past the player's height, switch the player's `position` to `fixed`.

```
&.floating-video {
    position: fixed;
    right: 0;
    bottom: 240px;
    z-index: 10;
    border-radius: 16px 16px ;
    width: 420px !important;
    height: 282px !important;
    animation: popin 0.5s ease-in-out forwards;
    font-size: 16px

    @keyframes popin {
      to {
        bottom: 240px;
      }
    }
```

### 8.2 Listening to the scroll event

```
 document.addEventListener('scroll', function(e) {
 // 當播放器不是暫停，捲動才作用
if (!that.player.paused && document.scrollTop > videoHeight) {
	// 當不是浮動的狀態
   if (!that.isFloatingVideo) {
       that.isFloatingVideo = true  // 用來控制 class 是不是浮動的樣式
   } else {
     that.isFloatingVideo = false
     }
	 }
 })
```

## 9. Custom-player full-screen
### 9.1 A custom player has many features; on PC you can easily go full-screen with the browser API.

```
handleFull() {
       const ele = this.player
       if (ele.requestFullscreen) {
         ele.requestFullscreen()
       } else if (ele.mozRequestFullScreen) {
         ele.mozRequestFullScreen()
       } else if (ele.webkitRequestFullScreen) {
         ele.webkitRequestFullScreen()
       } else if (ele.webkitEnterFullscreen) {
         ele.webkitEnterFullscreen()
       } else if (ele.webkitRequestFullscreen) {
         ele.webkitRequestFullscreen()
       } else if (ele.msRequestFullscreen) {
         ele.msRequestFullscreen()
       }
},
```

### 9.2 Mobile is a different story — you have to overlay an absolute-positioned `div` to simulate full-screen.
See [Bilibili's custom player](https://www.bilibili.com/) for reference.
![Bilibili-style mobile video player with danmu comments over a water scene](https://blog.markkulab.net/content/markku/posts/live-streaming-player/images/Cqp9Il0.png)
![Mobile video player interface with overlaid bullet comments](https://blog.markkulab.net/content/markku/posts/live-streaming-player/images/sMZBXGK.png)

---

## About this article and its author

Originally published on [Mark Ku's Tech Notes](https://blog.markkulab.net/en/post/live-streaming-player)

License: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — when reusing or quoting, credit the author and link back to the original

### About the author

**[Mark Ku](https://blog.markkulab.net/en/author/mark-ku)** — Software Solution Provider

- 10+ years senior software engineer, now an AI Builder
- Focused on large-platform architecture — North-American e-commerce, AI SaaS subscription billing
- Combining AI Agents and automation to build evolvable product foundations

### Free tools built by the author

All of these are free to use:

- [Free PDF Sign Tool](https://blog.markkulab.net/en/tools/pdf-sign): Online PDF sign tool — draw, type, or upload a signature, then drag, resize, and download. Everything runs in your browser; nothing is uploaded.
- [VS Code Refactory](https://blog.markkulab.net/en/tools/refactory): Refactory is a VS Code refactoring extension: 34 actions plus a 37-rule code-smell inspection layer with a Code Health dashboard, across 18 languages, backed by 534 tests. It learns your repo's conventions: where interfaces live, where DI is registered, whether 'use client' belongs. It ranks files by git churn × complexity so you know what to fix first, and hands any smell to the Claude Code already on your machine. Free to use, and your source never leaves your computer.
- [DB-Kit Database Manager](https://blog.markkulab.net/en/tools/db-kit): DB-Kit is a lightweight, cross-platform database manager built with Tauri + Rust + React. Manage MySQL, MariaDB, PostgreSQL, SQL Server, Oracle, SQLite, MongoDB, Redis, Kafka, Elasticsearch and RabbitMQ from one consistent interface: passwords encrypted in the OS keychain, SSH tunnels, full CRUD, a visual query builder, stacked multi-statement result sets, cross-connection data transfer and compare/sync, Excel / CSV import & export, visualized execution plans, ER diagrams, scheduled backups, SQL stress testing with p50–p99 latency percentiles, a 15-rule SQL review engine, Kafka message browsing with monitoring & alerts, a bilingual UI (Traditional Chinese / English), a built-in AI assistant (natural-language SQL, AI review and tuning advice) and the dbk CLI. Free and open source (MIT), with installers for Windows, macOS and Linux.
- [VS Code Super Mermaid](https://blog.markkulab.net/en/tools/super-mermaid): Super Mermaid is a VS Code extension for beautiful Mermaid diagrams out of the box: auto-colored live preview, mouse pan & zoom, high-res PNG / SVG export, 21 templates and multiple themes. Free and open source (MIT).
- [React Super Mermaid](https://blog.markkulab.net/en/tools/react-super-mermaid): react-super-mermaid is an open-source React component library: render beautiful Mermaid diagrams with a single <MermaidViewer>, with built-in colorful / sketch themes, pan & zoom, in-diagram search, and high-res SVG / PNG export. Lightweight, SSR-safe, fully typed. Free and open source (MIT).
- [Jira / Confluence Super Mermaid](https://blog.markkulab.net/en/tools/jira-super-mermaid): An Atlassian Forge app: write Mermaid syntax directly inside a Jira issue or a Confluence page and get flowcharts, sequence diagrams, state machines and Gantt charts. 11 diagram types, SVG / PNG export, light and dark themes, full CJK support. Runs on Atlassian: your diagrams live in your own site and the app calls no third-party service. Free, coming soon to the Atlassian Marketplace.
- [Mermaid Live Preview](https://blog.markkulab.net/en/tools/mermaid-preview): Write Mermaid in your browser, see it render instantly, and share the whole diagram as a single link. No sign-up, nothing uploaded to a server, and mermaid.live share links work as-is.
- [React Intl Phone Number](https://blog.markkulab.net/en/tools/react-intl-phone-number): react-intl-phone-number is an open-source React component: framework-agnostic and antd-free, with E.164 in/out, a searchable flag / country-code dropdown, configurable validation levels (strict / mobile-strict / loose), themeable CSS, and i18n — phone logic powered by google-libphonenumber. Lightweight and fully typed. Free and open source (MIT).
- [Uptime Kuma Cluster](https://blog.markkulab.net/en/tools/uptime-kuma-cluster): Turn single-node Uptime Kuma into a highly available cluster: OpenResty + Lua smart load balancing, shared MariaDB state, health checks and automatic failover, plus cluster-management REST APIs. One Docker Compose command to start. Free and open source (MIT).
- [Special Education](https://blog.markkulab.net/en/education): Learning materials crafted for special education students

### Daily podcasts

- [Mark's Tech Insights — Daily AI News](https://blog.markkulab.net/en/category/tech-news): Daily curated AI and tech trends. Catch the latest developments via audio summaries — covering AI applications, software architecture, DevOps, and engineering practice. — RSS: https://blog.markkulab.net/feed.xml
- [AI股市蝦聊](https://blog.markkulab.net/en/category/ai-stock-chat): Every trading day, an AI-analyzed take on the Taiwan stock market, delivered as a two-host conversation covering the session and the next-day outlook. — RSS: https://blog.markkulab.net/ai-stock-chat/feed.xml
- [開源好物週報](https://blog.markkulab.net/en/category/open-source-weekly): A weekly two-host pick of free open-source tools surfaced from real Hacker News, GitHub, and Reddit buzz — what pain they solve and the fastest way to get started. — RSS: https://blog.markkulab.net/open-source-weekly/feed.xml

### Newsletter

[Subscribe to the newsletter](https://blog.markkulab.net/en/subscribe) — Be the first to know about new posts. No spam, unsubscribe anytime.
