Skip to content

Instantly share code, notes, and snippets.

@olchyk98
Created January 23, 2025 01:50
Show Gist options
  • Select an option

  • Save olchyk98/57855a911c151817535189689491d919 to your computer and use it in GitHub Desktop.

Select an option

Save olchyk98/57855a911c151817535189689491d919 to your computer and use it in GitHub Desktop.
import mime from 'mime'
import { getSongAudioStream } from '../../../../../_db/song'
import { headers } from 'next/headers'
import { clamp } from '../../../../../../utils/clamp'
export async function GET (
_req: Request,
{ params }: { params: Promise<{ songId: string }> },
) {
const id = (await params).songId
if (!id || typeof id !== 'string') {
return new Response('Invalid ID.', { status: 400 })
}
const reqHeaders = await headers()
const range = reqHeaders.get('range') ?? 'bytes=0-'
const [ , from, to = Infinity ] = Array.from(range.matchAll(/bytes=(\d+)-(\d+)?/g))[0]
/**
* Note from when it was implemented.
* This was very painful. All you have to remember
* when you're reading this code is that the right boundary
* in the Range value ("to" value) is NON-INCLUSIVE.
* Meaning, if client is looking to get the entire
* file, they'll specify #contentLength - 1# (or Infinity).
*
* The client expects us to do the same thing
* for the response. Therefore Content-Length
* would be returned as normal, but right
* boundary for the Content-Range value
* would be #sliceLength -1#.
* */
const { stream, byteLength, filename } = await getSongAudioStream(id)
const audioByteLength = byteLength
const clampedFrom = clamp(Number(from), 0)
const clampedTo = clamp(Number(to) + 1, 0, audioByteLength)
const slicedAudioBuffer = await new Promise<Buffer>((res, rej) => {
const slicedAudioBuffer = Buffer.alloc(clampedTo - clampedFrom)
let cursor = 0
let writeOffset = 0
stream.on('data', (chunk: Buffer) => {
if (cursor > clampedTo) {
return res(slicedAudioBuffer)
}
for (let ma = 0; ma < chunk.byteLength; ++ma) {
if (cursor >= clampedFrom) {
slicedAudioBuffer[writeOffset] = chunk[ma]
writeOffset += 1
}
cursor += 1
}
})
stream.on('end', () => res(slicedAudioBuffer))
stream.on('error', (e) => rej(e))
})
const contentType = mime.getType(filename) ?? 'audio/mpeg'
return new Response(
slicedAudioBuffer,
{
status: 206,
headers: {
'Content-Type': contentType,
'Accept-Ranges': 'bytes',
'Content-Length': `${slicedAudioBuffer.byteLength}`,
'Content-Range': `bytes ${clampedFrom}-${clampedTo - 1}/${audioByteLength}`,
},
},
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment