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

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}` : ''
}`;
}