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

Add more HLS options #1

Merged
merged 1 commit into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "odo-stream",
"version": "1.2.0",
"version": "1.2.1",
"scripts": {
"dev": "next dev",
"build": "next build",
Expand Down
9 changes: 7 additions & 2 deletions src/app/api/live/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ export async function GET(): Promise<Response> {
`${process.env.RS_URL}/hls/live.stream.m3u8`,
)

// return response
return new NextResponse(response.body)
return new NextResponse(response.body, {
headers: {
'Content-Type':
response.headers.get('Content-Type') ||
'application/vnd.apple.mpegurl',
},
})
} catch (e: any) {
throw new Error(`Failed to fetch playlist: ${e.message}`, {
cause: e,
Expand Down
7 changes: 6 additions & 1 deletion src/app/api/segment/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ export async function GET(request: NextRequest): Promise<Response> {
`${process.env.RS_URL}/hls${requestUrl.pathname}`,
)

return new NextResponse(response.body)
return new NextResponse(response.body, {
headers: {
'Content-Type':
response.headers.get('Content-Type') || 'application/octet-stream',
},
})
} catch (e: any) {
throw new Error(`Failed to fetch segment: ${e.message}`, {
cause: e,
Expand Down
2 changes: 1 addition & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ async function getOnline() {
const res: Response = await fetch(`${process.env.RS_URL}/v1/states`)
const data = await res.json()

return data?.repeat_to_local_nginx?.type !== 'disconnected'
return data?.repeat_to_local_nginx?.type === 'connected'
} catch (e: any) {
throw new Error(`Failed to fetch stream state: ${e.message}`, {
cause: e,
Expand Down
15 changes: 13 additions & 2 deletions src/components/player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,19 @@ export type PlayerProps = {
}

const hlsConfig = {
liveDurationInfinity: true,
lowLatencyMode: true,
autoStartLoad: true, // auto play on load
backBufferLength: 0, // eliminate back buffer
enableWorker: true, // use workers
initialLiveManifestSize: 2, // preload 2 chunks before autostart
liveDurationInfinity: true, // instructs browser that video is live
liveMaxLatencyDuration: 10, // if higher than this, adujst to liveSyncDuration
liveSyncDuration: 3, // how close to live to target? shorter than 3sec causes frequent buffering issues
lowLatencyMode: true, // enable low latency mode
maxBufferLength: 10, // limit forward buffer
maxLiveSyncPlaybackRate: 2, // if running behind, speed up video
nudgeMaxRetry: 5, // increase retries before buffer stalled
progressive: true, // use fetch instead of xhr
testBandwidth: false, // disable auto bandwidth estimation
}

export function Player({ className, src }: PlayerProps): React.ReactNode {
Expand Down
6 changes: 5 additions & 1 deletion src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ export async function middleware(request: NextRequest) {
const requestUrl = new URL(request.url)
const response: NextResponse = NextResponse.next()

// add CORS
// CORS
response.headers.set('Access-Control-Allow-Credentials', 'true')
response.headers.set('Access-Control-Allow-Origin', requestUrl.origin)
response.headers.set('Access-Control-Allow-Methods', 'GET')

// Cache
response.headers.set('Cache-Control', 'no-cache, no-store, must-revalidate')
response.headers.set('Pragma', 'no-cache')

return response
}

Expand Down