import { captureError } from '../errors' import { hashMini } from '../utils/crypto' import { createTimer, logTestResult, performanceLogger, hashSlice } from '../utils/helpers' import { HTMLNote, count, modal } from '../utils/html' // inspired by // - https://privacycheck.sec.lrz.de/active/fp_cpt/fp_can_play_type.html // - https://arkenfox.github.io/TZP const getMimeTypeShortList = () => [ 'audio/ogg; codecs="vorbis"', 'audio/mpeg', 'audio/mpegurl', 'audio/wav; codecs="1"', 'audio/x-m4a', 'audio/aac', 'video/ogg; codecs="theora"', 'video/quicktime', 'video/mp4; codecs="avc1.42E01E"', 'video/webm; codecs="vp8"', 'video/webm; codecs="vp9"', 'video/x-matroska', ].sort() export default async function getMedia() { const getMimeTypes = () => { try { const mimeTypes = getMimeTypeShortList() const videoEl = document.createElement('video') const audioEl = new Audio() const isMediaRecorderSupported = 'MediaRecorder' in window const types = mimeTypes.reduce((acc, type) => { const data = { mimeType: type, audioPlayType: audioEl.canPlayType(type), videoPlayType: videoEl.canPlayType(type), mediaSource: MediaSource.isTypeSupported(type), mediaRecorder: isMediaRecorderSupported ? MediaRecorder.isTypeSupported(type) : false, } if (!data.audioPlayType && !data.videoPlayType && !data.mediaSource && !data.mediaRecorder) { return acc } // @ts-ignore acc.push(data) return acc }, []) return types } catch (error) { return } } try { const timer = createTimer() timer.start() const mimeTypes = getMimeTypes() logTestResult({ time: timer.stop(), test: 'media', passed: true }) return { mimeTypes } } catch (error) { logTestResult({ test: 'media', passed: false }) captureError(error) return } } export function mediaHTML(fp) { if (!fp.media) { return `
Media
mimes (0): ${HTMLNote.BLOCKED}
` } const { media: { mimeTypes, $hash, }, } = fp const header = `

audioPlayType
videoPlayType
mediaSource
mediaRecorder
P (Probably)
M (Maybe)
T (True)
` const invalidMimeTypes = !mimeTypes || !mimeTypes.length const mimes = invalidMimeTypes ? undefined : mimeTypes.map((type) => { const { mimeType, audioPlayType, videoPlayType, mediaSource, mediaRecorder } = type return ` ${audioPlayType == 'probably' ? 'P' : audioPlayType == 'maybe' ? 'M': '-'}${videoPlayType == 'probably' ? 'P' : videoPlayType == 'maybe' ? 'M': '-'}${mediaSource ? 'T' : '-'}${mediaRecorder ? 'T' : '-'}: ${mimeType} ` }) const mimesListLen = getMimeTypeShortList().length return `
${performanceLogger.getLog().media} Media${hashSlice($hash)}
mimes (${count(mimeTypes)}/${mimesListLen}): ${ invalidMimeTypes ? HTMLNote.BLOCKED : modal( 'creep-media-mimeTypes', header+mimes.join('
'), hashMini(mimeTypes), ) }
` }