2024-10-11, 11:49 AM
Hello everyone,
I'm setting up a caching solution for Jellyfin video transcoding using Cloudflare, and I've come across some questions regarding the best practices for caching video transcoding with Cloudflare Workers. I noticed that the caching documentation for Jellyfin seems to have been removed or changed on the official site, so I’m seeking advice from the community.
I’ve configured a Cloudflare Worker script to handle video caching for Jellyfin, specifically targeting requests to /videos/. The script normalizes the URL by removing various query parameters (e.g., api_key, DeviceId, PlaySessionId, etc.), and then attempts to fetch the requested resource from the cache. If not found, it fetches it from the origin server and caches the response.
Here is the Cloudflare Worker code I’m using:
Example Request
Here's an example of a request that would be processed:
Questions
1. Is this configuration optimal for caching transcoded video streams from Jellyfin? Are there any parameters that should not be removed from the cache key?
2. Are there any specific considerations or settings I should apply for Cloudflare's cache rules to avoid issues with video playback or session handling?
3. Since the Jellyfin documentation regarding caching is no longer available, does anyone have updated best practices for caching video streams or transcoding results?
I'm setting up a caching solution for Jellyfin video transcoding using Cloudflare, and I've come across some questions regarding the best practices for caching video transcoding with Cloudflare Workers. I noticed that the caching documentation for Jellyfin seems to have been removed or changed on the official site, so I’m seeking advice from the community.
I’ve configured a Cloudflare Worker script to handle video caching for Jellyfin, specifically targeting requests to /videos/. The script normalizes the URL by removing various query parameters (e.g., api_key, DeviceId, PlaySessionId, etc.), and then attempts to fetch the requested resource from the cache. If not found, it fetches it from the origin server and caches the response.
Here is the Cloudflare Worker code I’m using:
Code:
addEventListener('fetch', (event) => {
event.respondWith(handleRequest(event))
})
async function handleRequest(event) {
const request = event.request
const url = new URL(request.url)
if (url.pathname.startsWith('/videos/')) {
const paramsToRemove = [
'api_key',
'DeviceId',
'PlaySessionId',
// 'MediaSourceId',
// 'VideoCodec',
// 'AudioCodec',
// 'AudioStreamIndex',
// 'VideoBitrate',
// 'AudioBitrate',
// 'AudioSampleRate',
// 'MaxFramerate',
// 'TranscodingMaxAudioChannels',
// 'RequireAvc',
// 'Tag',
// 'SegmentContainer',
// 'MinSegments',
// 'BreakOnNonKeyFrames',
// 'h264-level',
// 'h264-videobitdepth',
// 'h264-profile',
// 'h264-audiochannels',
// 'aac-profile',
// 'av1-profile',
// 'av1-rangetype',
// 'av1-level',
// 'hevc-profile',
// 'hevc-rangetype',
// 'hevc-level',
// 'hevc-deinterlace',
// 'h264-rangetype',
// 'h264-deinterlace',
// 'TranscodeReasons',
// 'runtimeTicks',
// 'actualSegmentLengthTicks'
]
for (const param of paramsToRemove) {
url.searchParams.delete(param)
}
const normalizedUrl = url.toString()
const cacheRequest = new Request(normalizedUrl, {
method: request.method,
headers: request.headers,
})
const cache = caches.default
let response = await cache.match(cacheRequest)
if (!response) {
response = await fetch(request)
if (response.ok) {
const responseClone = response.clone()
event.waitUntil(
cache.put(
cacheRequest,
responseClone
)
)
}
}
return response
}
return fetch(request)
}
Example Request
Here's an example of a request that would be processed:
Code:
/videos/REDACTED/hls1/main/1.mp4?DeviceId=REDACTED&MediaSourceId=REDACTED&VideoCodec=av1,hevc,h264,hevc&AudioCodec=aac&AudioStreamIndex=2&VideoBitrate=59808000&AudioBitrate=192000&AudioSampleRate=44100&MaxFramerate=23.976025&PlaySessionId=REDACTED&api_key=REDACTED&TranscodingMaxAudioChannels=2&RequireAvc=false&Tag=REDACTED&SegmentContainer=mp4&MinSegments=2&BreakOnNonKeyFrames=True&hevc-level=153&hevc-videobitdepth=10&hevc-profile=main10&hevc-audiochannels=2&aac-profile=lc&av1-profile=main&av1-rangetype=SDR,HDR10,HLG&av1-level=19&hevc-rangetype=SDR,HDR10,HLG&hevc-deinterlace=true&h264-profile=high,main,baseline,constrainedbaseline,high10&h264-rangetype=SDR&h264-level=52&h264-deinterlace=true&TranscodeReasons=ContainerNotSupported,%REDACTED&runtimeTicks=75080000&actualSegmentLengthTicks=136800000
Questions
1. Is this configuration optimal for caching transcoded video streams from Jellyfin? Are there any parameters that should not be removed from the cache key?
2. Are there any specific considerations or settings I should apply for Cloudflare's cache rules to avoid issues with video playback or session handling?
3. Since the Jellyfin documentation regarding caching is no longer available, does anyone have updated best practices for caching video streams or transcoding results?