fix: airplay

This commit is contained in:
shinya
2025-06-20 13:15:34 +08:00
parent 7aba6c92eb
commit 10afbce6cb
16 changed files with 34 additions and 285 deletions

14
.github/FUNDING.yml vendored
View File

@@ -1,14 +0,0 @@
# !STARTERCONF You can delete this file :) Your support is much appreciated!
# These are supported funding model platforms
github: theodorusclarence
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: ['https://saweria.co/theodorusclarence']

View File

@@ -1,9 +0,0 @@
# https://github.com/robvanderleek/create-issue-branch#option-2-configure-github-action
# ex: i4-lower_camel_upper
branchName: 'i${issue.number}-${issue.title,}'
branches:
- label: epic
skip: true
- label: debt
skip: true

View File

@@ -1,15 +0,0 @@
# Description & Technical Solution
Describe problems, if any, clearly and concisely.
Summarize the impact to the system.
Please also include relevant motivation and context.
Please include a summary of the technical solution and how it solves the problem.
# Checklist
- [ ] I have commented my code, particularly in hard-to-understand areas.
- [ ] Already rebased against main branch.
# Screenshots
Provide screenshots or videos of the changes made if any.

View File

@@ -1,14 +0,0 @@
name: Create Branch from Issue
on:
issues:
types: [assigned]
jobs:
create_issue_branch_job:
runs-on: ubuntu-latest
steps:
- name: Create Issue Branch
uses: robvanderleek/create-issue-branch@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,16 +0,0 @@
name: 'Issue Autolink'
on:
pull_request:
types: [opened]
jobs:
issue-links:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: tkt-actions/add-issue-links@v1.8.1
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'
branch-prefix: 'i'
resolve: 'true'

View File

@@ -1,44 +0,0 @@
name: Code Check
on:
push:
branches:
- main
pull_request: {}
concurrency:
group: ${{ github.job }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
name: ⬣ ESLint, ʦ TypeScript, 💅 Prettier, and 🃏 Test
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v4
- name: 🤌 Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: 📥 Download deps
run: pnpm install --frozen-lockfile
- name: 🔬 Lint
run: pnpm run lint:strict
- name: 🔎 Type check
run: pnpm run typecheck
- name: 💅 Prettier check
run: pnpm run format:check
- name: 🃏 Run jest
run: pnpm run test

View File

@@ -1,17 +0,0 @@
name: release-please
on:
# !STARTERCONF Choose your preferred event
# !Option 1: Manual Trigger from GitHub
workflow_dispatch:
# !Option 2: Release on every push on main branch
# push:
# branches:
# - main
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: google-github-actions/release-please-action@v3
with:
release-type: node
package-name: release-please-action

View File

@@ -1,8 +0,0 @@
import React, { SVGProps } from 'react';
const SvgrMock = React.forwardRef<SVGSVGElement, SVGProps<SVGSVGElement>>(
(props, ref) => <svg ref={ref} {...props} />
);
export const ReactComponent = SvgrMock;
export default SvgrMock;

View File

@@ -1,15 +0,0 @@
// !STARTERCONF You should delete this page
import { render, screen } from '@testing-library/react';
import HomePage from '@/app/page';
describe('Homepage', () => {
it('renders the Components', () => {
render(<HomePage />);
const heading = screen.getByText(/A starter for Next.js/i);
expect(heading).toBeInTheDocument();
});
});

View File

@@ -138,7 +138,6 @@ function PlayPageClient() {
sources.forEach((s) => s.remove());
const sourceEl = document.createElement('source');
sourceEl.src = url;
sourceEl.type = 'video/mp4'; // 默认类型HLS 会被 Artplayer/Hls 处理
video.appendChild(sourceEl);
}
@@ -435,46 +434,41 @@ function PlayPageClient() {
return;
}
if (Hls.isSupported()) {
if (video.hls) {
video.hls.destroy();
}
const hls = new Hls({
debug: false,
enableWorker: true,
lowLatencyMode: true,
backBufferLength: 90,
});
hls.loadSource(url);
hls.attachMedia(video);
video.hls = hls;
hls.on(Hls.Events.ERROR, function (event: any, data: any) {
console.error('HLS Error:', event, data);
if (data.fatal) {
switch (data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
console.log('网络错误,尝试恢复...');
hls.startLoad();
break;
case Hls.ErrorTypes.MEDIA_ERROR:
console.log('媒体错误,尝试恢复...');
hls.recoverMediaError();
break;
default:
console.log('无法恢复的错误');
hls.destroy();
break;
}
}
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
// Safari 原生支持 HLS
video.src = url;
} else {
console.error('此浏览器不支持 HLS');
if (video.hls) {
video.hls.destroy();
}
const hls = new Hls({
debug: false,
enableWorker: true,
lowLatencyMode: true,
backBufferLength: 90,
});
hls.loadSource(url);
hls.attachMedia(video);
video.hls = hls;
ensureVideoSource(video, url);
hls.on(Hls.Events.ERROR, function (event: any, data: any) {
console.error('HLS Error:', event, data);
if (data.fatal) {
switch (data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
console.log('网络错误,尝试恢复...');
hls.startLoad();
break;
case Hls.ErrorTypes.MEDIA_ERROR:
console.log('媒体错误,尝试恢复...');
hls.recoverMediaError();
break;
default:
console.log('无法恢复的错误');
hls.destroy();
break;
}
}
});
},
},
icons: {

View File

@@ -1,7 +0,0 @@
export const siteConfig = {
title: 'Next.js + Tailwind CSS + TypeScript Starter',
description:
'A starter for Next.js, Tailwind CSS, and TypeScript with Absolute Import, Seo, Link component, pre-configured with Husky',
/** Without additional '/' on the end, e.g. https://theodorusclarence.com */
url: 'https://tsnext-tw.thcl.dev',
};

View File

@@ -1,6 +0,0 @@
export const isProd = process.env.NODE_ENV === 'production';
export const isLocal = process.env.NODE_ENV === 'development';
export const showLogger = isLocal
? true
: process.env.NEXT_PUBLIC_SHOW_LOGGER === 'true' ?? false;

View File

@@ -1,21 +0,0 @@
/* eslint-disable @typescript-eslint/no-namespace */
/**
* Configuration for type-safe environment variables.
* Imported through src/app/page.tsx
* @see https://x.com/mattpocockuk/status/1760991147793449396
*/
import { z } from 'zod';
const envVariables = z.object({
NEXT_PUBLIC_SHOW_LOGGER: z.enum(['true', 'false']).optional(),
NEXT_PUBLIC_STORAGE_TYPE: z.enum(['localstorage', 'database']).optional(),
});
envVariables.parse(process.env);
declare global {
namespace NodeJS {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface ProcessEnv extends z.infer<typeof envVariables> {}
}
}

View File

@@ -1,13 +0,0 @@
export function getFromLocalStorage(key: string): string | null {
if (typeof window !== 'undefined') {
return window.localStorage.getItem(key);
}
return null;
}
export function getFromSessionStorage(key: string): string | null {
if (typeof sessionStorage !== 'undefined') {
return sessionStorage.getItem(key);
}
return null;
}

View File

@@ -1,19 +0,0 @@
/* eslint-disable no-console */
import { showLogger } from '@/constant/env';
/**
* A logger function that will only logs on development
* @param object - The object to log
* @param comment - Autogenerated with `lg` snippet
*/
export default function logger(object: unknown, comment?: string): void {
if (!showLogger) return;
console.log(
'%c ============== INFO LOG \n',
'color: #22D3EE',
`${typeof window !== 'undefined' && window?.location.pathname}\n`,
`=== ${comment ?? ''}\n`,
object
);
}

View File

@@ -1,27 +0,0 @@
type OpenGraphType = {
siteName: string;
description: string;
templateTitle?: string;
logo?: string;
};
// !STARTERCONF This OG is generated from https://github.com/theodorusclarence/og
// Please clone them and self-host if your site is going to be visited by many people.
// Then change the url and the default logo.
export function openGraph({
siteName,
templateTitle,
description,
// !STARTERCONF Or, you can use my server with your own logo.
logo = 'https://og.<your-domain>/images/logo.jpg',
}: OpenGraphType): string {
const ogLogo = encodeURIComponent(logo);
const ogSiteName = encodeURIComponent(siteName.trim());
const ogTemplateTitle = templateTitle
? encodeURIComponent(templateTitle.trim())
: undefined;
const ogDesc = encodeURIComponent(description.trim());
return `https://og.<your-domain>/api/general?siteName=${ogSiteName}&description=${ogDesc}&logo=${ogLogo}${
ogTemplateTitle ? `&templateTitle=${ogTemplateTitle}` : ''
}`;
}