mirror of
https://github.com/MoonTechLab/LunaTV.git
synced 2026-02-21 09:14:42 +08:00
fix: airplay
This commit is contained in:
14
.github/FUNDING.yml
vendored
14
.github/FUNDING.yml
vendored
@@ -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']
|
||||
9
.github/issue-branch.yml
vendored
9
.github/issue-branch.yml
vendored
@@ -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
|
||||
15
.github/pull_request_template.md
vendored
15
.github/pull_request_template.md
vendored
@@ -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.
|
||||
14
.github/workflows/create-branch.yml
vendored
14
.github/workflows/create-branch.yml
vendored
@@ -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 }}
|
||||
16
.github/workflows/issue-autolink.yml
vendored
16
.github/workflows/issue-autolink.yml
vendored
@@ -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'
|
||||
44
.github/workflows/lint.yml
vendored
44
.github/workflows/lint.yml
vendored
@@ -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
|
||||
17
.github/workflows/release-please.yml
vendored
17
.github/workflows/release-please.yml
vendored
@@ -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
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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: {
|
||||
|
||||
@@ -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',
|
||||
};
|
||||
@@ -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;
|
||||
@@ -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> {}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
@@ -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}` : ''
|
||||
}`;
|
||||
}
|
||||
Reference in New Issue
Block a user