mirror of
https://github.com/jellyfin/jellyfin-vue.git
synced 2024-10-07 11:33:40 +00:00
chore: delete unneeded playbackProfiles directory
This commit is contained in:
parent
d7065ac7bb
commit
e60a8bee15
@ -1,109 +0,0 @@
|
||||
import { DirectPlayProfile, DlnaProfileType } from '@jellyfin/client-axios';
|
||||
import { Context } from '@nuxt/types';
|
||||
import { getSupportedMP4VideoCodecs } from './helpers/mp4VideoFormats';
|
||||
import { getSupportedMP4AudioCodecs } from './helpers/mp4AudioFormats';
|
||||
import { hasMkvSupport } from './helpers/transcodingFormats';
|
||||
import { getSupportedWebMAudioCodecs } from './helpers/webmAudioFormats';
|
||||
import { getSupportedWebMVideoCodecs } from './helpers/webmVideoFormats';
|
||||
import { getSupportedAudioCodecs } from './helpers/audioFormats';
|
||||
|
||||
/**
|
||||
* Returns a valid DirectPlayProfile for the current platform.
|
||||
*
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {Array<DirectPlayProfile>} An array of direct play profiles for the current platform.
|
||||
*/
|
||||
export function getDirectPlayProfiles(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): Array<DirectPlayProfile> {
|
||||
const DirectPlayProfiles: DirectPlayProfile[] = [];
|
||||
|
||||
const webmVideoCodecs = getSupportedWebMVideoCodecs(
|
||||
context,
|
||||
videoTestElement
|
||||
);
|
||||
const webmAudioCodecs = getSupportedWebMAudioCodecs(
|
||||
context,
|
||||
videoTestElement
|
||||
);
|
||||
|
||||
const mp4VideoCodecs = getSupportedMP4VideoCodecs(context, videoTestElement);
|
||||
const mp4AudioCodecs = getSupportedMP4AudioCodecs(context, videoTestElement);
|
||||
|
||||
if (webmVideoCodecs.length) {
|
||||
DirectPlayProfiles.push({
|
||||
Container: 'webm',
|
||||
Type: DlnaProfileType.Video,
|
||||
VideoCodec: webmVideoCodecs.join(','),
|
||||
AudioCodec: webmAudioCodecs.join(',')
|
||||
});
|
||||
}
|
||||
|
||||
if (mp4VideoCodecs.length) {
|
||||
DirectPlayProfiles.push({
|
||||
Container: 'mp4,m4v',
|
||||
Type: DlnaProfileType.Video,
|
||||
VideoCodec: mp4VideoCodecs.join(','),
|
||||
AudioCodec: mp4AudioCodecs.join(',')
|
||||
});
|
||||
}
|
||||
|
||||
if (hasMkvSupport(context, videoTestElement) && mp4VideoCodecs.length) {
|
||||
DirectPlayProfiles.push({
|
||||
Container: 'mkv',
|
||||
Type: DlnaProfileType.Video,
|
||||
VideoCodec: mp4VideoCodecs.join(','),
|
||||
AudioCodec: mp4AudioCodecs.join(',')
|
||||
});
|
||||
}
|
||||
|
||||
const supportedAudio = [
|
||||
'opus',
|
||||
'mp3',
|
||||
'mp2',
|
||||
'aac',
|
||||
'flac',
|
||||
'alac',
|
||||
'webma',
|
||||
'wma',
|
||||
'wav',
|
||||
'ogg',
|
||||
'oga'
|
||||
];
|
||||
|
||||
for (const audioFormat of supportedAudio.filter((format) =>
|
||||
getSupportedAudioCodecs(context, format)
|
||||
)) {
|
||||
DirectPlayProfiles.push({
|
||||
Container: audioFormat,
|
||||
Type: DlnaProfileType.Audio
|
||||
});
|
||||
|
||||
if (audioFormat === 'opus' || audioFormat === 'webma') {
|
||||
DirectPlayProfiles.push({
|
||||
Container: 'webm',
|
||||
Type: DlnaProfileType.Audio,
|
||||
AudioCodec: audioFormat
|
||||
});
|
||||
}
|
||||
|
||||
// aac also appears in the m4a and m4b container
|
||||
if (audioFormat === 'aac' || audioFormat === 'alac') {
|
||||
DirectPlayProfiles.push({
|
||||
Container: 'm4a',
|
||||
AudioCodec: audioFormat,
|
||||
Type: DlnaProfileType.Audio
|
||||
});
|
||||
|
||||
DirectPlayProfiles.push({
|
||||
Container: 'm4b',
|
||||
AudioCodec: audioFormat,
|
||||
Type: DlnaProfileType.Audio
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return DirectPlayProfiles;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
import { Context } from '@nuxt/types';
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {string} format - Audio codec to test
|
||||
* @returns {boolean} Determines if audio codec is supported
|
||||
*/
|
||||
export function getSupportedAudioCodecs(
|
||||
context: Context,
|
||||
format: string
|
||||
): boolean {
|
||||
let typeString;
|
||||
|
||||
if (format === 'flac' && context.$browser.isTv()) {
|
||||
return true;
|
||||
} else if (format === 'wma' && context.$browser.isTizen()) {
|
||||
return true;
|
||||
} else if (format === 'asf' && context.$browser.isTv()) {
|
||||
return true;
|
||||
} else if (format === 'opus') {
|
||||
if (!context.$browser.isWebOS()) {
|
||||
typeString = 'audio/ogg; codecs="opus"';
|
||||
|
||||
return !!document
|
||||
.createElement('audio')
|
||||
.canPlayType(typeString)
|
||||
.replace(/no/, '');
|
||||
}
|
||||
|
||||
return false;
|
||||
} else if (format === 'alac' && context.$browser.isApple()) {
|
||||
return true;
|
||||
} else if (format === 'webma') {
|
||||
typeString = 'audio/webm';
|
||||
} else if (format === 'mp2') {
|
||||
typeString = 'audio/mpeg';
|
||||
} else {
|
||||
typeString = 'audio/' + format;
|
||||
}
|
||||
|
||||
return !!document
|
||||
.createElement('audio')
|
||||
.canPlayType(typeString)
|
||||
.replace(/no/, '');
|
||||
}
|
@ -1,352 +0,0 @@
|
||||
import {
|
||||
CodecProfile,
|
||||
CodecType,
|
||||
ProfileConditionType,
|
||||
ProfileCondition,
|
||||
ProfileConditionValue
|
||||
} from '@jellyfin/client-axios';
|
||||
import { Context } from '@nuxt/types';
|
||||
|
||||
/**
|
||||
* Gets the max video bitrate
|
||||
*
|
||||
* @param {Context} context - Nuxt context
|
||||
* @returns {number | null} Returns the MaxVideoBitrate
|
||||
*/
|
||||
function getGlobalMaxVideoBitrate(context: Context): number | null {
|
||||
let isTizenFhd = false;
|
||||
|
||||
if (context.$browser.isTizen() && window.webapis) {
|
||||
isTizenFhd = !window.webapis.productinfo.isUdPanelSupported();
|
||||
}
|
||||
|
||||
// TODO: These valus are taken directly from Jellyfin-web.
|
||||
// The source of them needs to be investigated.
|
||||
if (context.$browser.isPs4()) {
|
||||
return 8000000;
|
||||
}
|
||||
|
||||
if (context.$browser.isXbox()) {
|
||||
return 12000000;
|
||||
}
|
||||
|
||||
if (context.$browser.isTizen() && isTizenFhd) {
|
||||
return 20000000;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a profile condition object for use in device playback profiles.
|
||||
*
|
||||
* @param {ProfileConditionValue} Property - Value for the property
|
||||
* @param {ProfileConditionType} Condition - Condition that the property must comply with
|
||||
* @param {string} Value - Value to check in the condition
|
||||
* @param {boolean} IsRequired - Whether this property is required
|
||||
* @returns {ProfileCondition} - Constructed ProfileCondition object
|
||||
*/
|
||||
function createProfileCondition(
|
||||
Property: ProfileConditionValue,
|
||||
Condition: ProfileConditionType,
|
||||
Value: string,
|
||||
IsRequired = false
|
||||
): ProfileCondition {
|
||||
return {
|
||||
Condition,
|
||||
Property,
|
||||
Value,
|
||||
IsRequired
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {ProfileCondition[]} - Array of ACC Profile conditions
|
||||
*/
|
||||
export function getAacCodecProfileConditions(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): ProfileCondition[] {
|
||||
const supportsSecondaryAudio = context.$browser.isTizen();
|
||||
|
||||
const conditions: ProfileCondition[] = [];
|
||||
|
||||
// Handle he-aac not supported
|
||||
if (
|
||||
!videoTestElement
|
||||
.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.5"')
|
||||
.replace(/no/, '')
|
||||
) {
|
||||
// TODO: This needs to become part of the stream url in order to prevent stream copy
|
||||
conditions.push(
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.AudioProfile,
|
||||
ProfileConditionType.NotEquals,
|
||||
'HE-AAC'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!supportsSecondaryAudio) {
|
||||
conditions.push(
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.IsSecondaryAudio,
|
||||
ProfileConditionType.Equals,
|
||||
'false'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {CodecProfile[]} - Array containing the different profiles for the client
|
||||
*/
|
||||
export function getCodecProfiles(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): CodecProfile[] {
|
||||
const CodecProfiles: CodecProfile[] = [];
|
||||
|
||||
const aacProfileConditions = getAacCodecProfileConditions(
|
||||
context,
|
||||
videoTestElement
|
||||
);
|
||||
|
||||
const supportsSecondaryAudio = context.$browser.isTizen();
|
||||
|
||||
if (aacProfileConditions.length) {
|
||||
CodecProfiles.push({
|
||||
Type: CodecType.VideoAudio,
|
||||
Codec: 'aac',
|
||||
Conditions: aacProfileConditions
|
||||
});
|
||||
}
|
||||
|
||||
if (!supportsSecondaryAudio) {
|
||||
CodecProfiles.push({
|
||||
Type: CodecType.VideoAudio,
|
||||
Conditions: [
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.IsSecondaryAudio,
|
||||
ProfileConditionType.Equals,
|
||||
'false'
|
||||
)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
let maxH264Level = 42;
|
||||
let h264Profiles = 'high|main|baseline|constrained baseline';
|
||||
|
||||
if (
|
||||
context.$browser.isTv() ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="avc1.640833"')
|
||||
.replace(/no/, '')
|
||||
) {
|
||||
maxH264Level = 51;
|
||||
}
|
||||
|
||||
if (
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="avc1.640834"')
|
||||
.replace(/no/, '')
|
||||
) {
|
||||
maxH264Level = 52;
|
||||
}
|
||||
|
||||
if (
|
||||
context.$browser.isTizen() ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="avc1.6e0033"')
|
||||
.replace(/no/, '')
|
||||
) {
|
||||
// TODO: These tests are passing in Safari, but playback is failing
|
||||
if (
|
||||
!context.$browser.isApple() ||
|
||||
!context.$browser.isWebOS() ||
|
||||
!(context.$browser.isEdge() && !context.$browser.isChromiumBased())
|
||||
) {
|
||||
h264Profiles += '|high 10';
|
||||
}
|
||||
}
|
||||
|
||||
let maxHevcLevel = 120;
|
||||
let hevcProfiles = 'main';
|
||||
|
||||
// HEVC Main profile, Level 4.1
|
||||
if (
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hvc1.1.4.L123"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hev1.1.4.L123"')
|
||||
.replace(/no/, '')
|
||||
) {
|
||||
maxHevcLevel = 123;
|
||||
}
|
||||
|
||||
// HEVC Main10 profile, Level 4.1
|
||||
if (
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hvc1.2.4.L123"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hev1.2.4.L123"')
|
||||
.replace(/no/, '')
|
||||
) {
|
||||
maxHevcLevel = 123;
|
||||
hevcProfiles = 'main|main 10';
|
||||
}
|
||||
|
||||
// HEVC Main10 profile, Level 5.1
|
||||
if (
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hvc1.2.4.L153"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hev1.2.4.L153"')
|
||||
.replace(/no/, '')
|
||||
) {
|
||||
maxHevcLevel = 153;
|
||||
hevcProfiles = 'main|main 10';
|
||||
}
|
||||
|
||||
// HEVC Main10 profile, Level 6.1
|
||||
if (
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hvc1.2.4.L183"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hev1.2.4.L183"')
|
||||
.replace(/no/, '')
|
||||
) {
|
||||
maxHevcLevel = 183;
|
||||
hevcProfiles = 'main|main 10';
|
||||
}
|
||||
|
||||
const hevcCodecProfileConditions: ProfileCondition[] = [
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.IsAnamorphic,
|
||||
ProfileConditionType.NotEquals,
|
||||
'true'
|
||||
),
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.VideoProfile,
|
||||
ProfileConditionType.EqualsAny,
|
||||
hevcProfiles
|
||||
),
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.VideoLevel,
|
||||
ProfileConditionType.LessThanEqual,
|
||||
maxHevcLevel.toString()
|
||||
)
|
||||
];
|
||||
|
||||
const h264CodecProfileConditions: ProfileCondition[] = [
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.IsAnamorphic,
|
||||
ProfileConditionType.NotEquals,
|
||||
'true'
|
||||
),
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.VideoProfile,
|
||||
ProfileConditionType.EqualsAny,
|
||||
h264Profiles
|
||||
),
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.VideoLevel,
|
||||
ProfileConditionType.LessThanEqual,
|
||||
maxH264Level.toString()
|
||||
)
|
||||
];
|
||||
|
||||
if (!context.$browser.isTv()) {
|
||||
h264CodecProfileConditions.push(
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.IsInterlaced,
|
||||
ProfileConditionType.NotEquals,
|
||||
'true'
|
||||
)
|
||||
);
|
||||
hevcCodecProfileConditions.push(
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.IsInterlaced,
|
||||
ProfileConditionType.NotEquals,
|
||||
'true'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const globalMaxVideoBitrate = (
|
||||
getGlobalMaxVideoBitrate(context) || ''
|
||||
).toString();
|
||||
|
||||
if (globalMaxVideoBitrate) {
|
||||
h264CodecProfileConditions.push(
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.VideoBitrate,
|
||||
ProfileConditionType.LessThanEqual,
|
||||
globalMaxVideoBitrate,
|
||||
true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (globalMaxVideoBitrate) {
|
||||
hevcCodecProfileConditions.push(
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.VideoBitrate,
|
||||
ProfileConditionType.LessThanEqual,
|
||||
globalMaxVideoBitrate,
|
||||
true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// On iOS 12.x, for TS container max h264 level is 4.2
|
||||
if (
|
||||
context.$browser.isApple() &&
|
||||
context.$browser.isMobile() &&
|
||||
(context.$browser.safariVersion() as number) < 13
|
||||
) {
|
||||
const codecProfile = {
|
||||
Type: CodecType.Video,
|
||||
Codec: 'h264',
|
||||
Container: 'ts',
|
||||
Conditions: h264CodecProfileConditions.filter((condition) => {
|
||||
return condition.Property !== 'VideoLevel';
|
||||
})
|
||||
};
|
||||
|
||||
codecProfile.Conditions.push(
|
||||
createProfileCondition(
|
||||
ProfileConditionValue.VideoLevel,
|
||||
ProfileConditionType.LessThanEqual,
|
||||
'42'
|
||||
)
|
||||
);
|
||||
|
||||
CodecProfiles.push(codecProfile);
|
||||
}
|
||||
|
||||
CodecProfiles.push({
|
||||
Type: CodecType.Video,
|
||||
Codec: 'h264',
|
||||
Conditions: h264CodecProfileConditions
|
||||
});
|
||||
|
||||
CodecProfiles.push({
|
||||
Type: CodecType.Video,
|
||||
Codec: 'hevc',
|
||||
Conditions: hevcCodecProfileConditions
|
||||
});
|
||||
|
||||
return CodecProfiles;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
import { Context } from '@nuxt/types';
|
||||
import { getSupportedAudioCodecs } from './audioFormats';
|
||||
import {
|
||||
hasAacSupport,
|
||||
hasAc3InHlsSupport,
|
||||
hasAc3Support,
|
||||
hasEac3Support,
|
||||
hasMp3AudioSupport
|
||||
} from './mp4AudioFormats';
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {string[]} List of supported FMP4 audio codecs
|
||||
*/
|
||||
export function getSupportedFmp4AudioCodecs(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
|
||||
if (hasAacSupport(videoTestElement)) {
|
||||
codecs.push('aac');
|
||||
}
|
||||
|
||||
if (hasMp3AudioSupport(videoTestElement)) {
|
||||
codecs.push('mp3');
|
||||
}
|
||||
|
||||
if (hasAc3Support(context, videoTestElement)) {
|
||||
if (hasAc3InHlsSupport(context, videoTestElement)) {
|
||||
codecs.push('ac3');
|
||||
|
||||
if (hasEac3Support(context, videoTestElement)) {
|
||||
codecs.push('eac3');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getSupportedAudioCodecs(context, 'flac')) {
|
||||
if (!context.$browser.isEdge()) {
|
||||
codecs.push('flac');
|
||||
}
|
||||
}
|
||||
|
||||
if (getSupportedAudioCodecs(context, 'alac')) {
|
||||
codecs.push('alac');
|
||||
}
|
||||
|
||||
return codecs;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
import { Context } from '@nuxt/types';
|
||||
import { hasH264Support, hasHevcSupport } from './mp4VideoFormats';
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {string[]} List of supported fmp4 video codecs
|
||||
*/
|
||||
export function getSupportedFmp4VideoCodecs(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
|
||||
if (
|
||||
(context.$browser.isApple() ||
|
||||
context.$browser.isEdge() ||
|
||||
context.$browser.isTizen() ||
|
||||
context.$browser.isWebOS()) &&
|
||||
hasHevcSupport(context, videoTestElement)
|
||||
) {
|
||||
codecs.push('hevc');
|
||||
}
|
||||
|
||||
if (
|
||||
hasH264Support(videoTestElement) &&
|
||||
(context.$browser.isChrome() ||
|
||||
context.$browser.isFirefox() ||
|
||||
context.$browser.isApple() ||
|
||||
context.$browser.isEdge() ||
|
||||
context.$browser.isTizen() ||
|
||||
context.$browser.isWebOS())
|
||||
) {
|
||||
codecs.push('h264');
|
||||
}
|
||||
|
||||
return codecs;
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
import { Context } from '@nuxt/types';
|
||||
import { hasH264Support, hasH265Support } from './mp4VideoFormats';
|
||||
import { hasEac3Support, hasAacSupport } from './mp4AudioFormats';
|
||||
import { getSupportedAudioCodecs } from './audioFormats';
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if the browser has AC3 in HLS support
|
||||
*/
|
||||
function supportsAc3InHls(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean | string {
|
||||
if (context.$browser.isTv()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (videoTestElement.canPlayType) {
|
||||
return (
|
||||
videoTestElement
|
||||
.canPlayType('application/x-mpegurl; codecs="avc1.42E01E, ac-3"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType(
|
||||
'application/vnd.apple.mpegURL; codecs="avc1.42E01E, ac-3"'
|
||||
)
|
||||
.replace(/no/, '')
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {string[]} Array of video codecs supported in HLS
|
||||
*/
|
||||
export function getHlsVideoCodecs(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const hlsVideoCodecs = [];
|
||||
|
||||
if (hasH264Support(videoTestElement)) {
|
||||
hlsVideoCodecs.push('h264');
|
||||
}
|
||||
|
||||
if (hasH265Support(context, videoTestElement) || context.$browser.isTv()) {
|
||||
hlsVideoCodecs.push('h265');
|
||||
hlsVideoCodecs.push('hevc');
|
||||
}
|
||||
|
||||
return hlsVideoCodecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {string[]} Array of audio codecs supported in HLS
|
||||
*/
|
||||
export function getHlsAudioCodecs(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const hlsVideoAudioCodecs = [];
|
||||
|
||||
if (supportsAc3InHls(context, videoTestElement)) {
|
||||
hlsVideoAudioCodecs.push('ac3');
|
||||
|
||||
if (hasEac3Support(context, videoTestElement)) {
|
||||
hlsVideoAudioCodecs.push('eac3');
|
||||
}
|
||||
}
|
||||
|
||||
if (hasAacSupport(videoTestElement)) {
|
||||
hlsVideoAudioCodecs.push('aac');
|
||||
}
|
||||
|
||||
if (getSupportedAudioCodecs(context, 'opus')) {
|
||||
hlsVideoAudioCodecs.push('opus');
|
||||
}
|
||||
|
||||
return hlsVideoAudioCodecs;
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
import { Context } from '@nuxt/types';
|
||||
import { hasVp8Support } from './mp4VideoFormats';
|
||||
import { getSupportedAudioCodecs } from './audioFormats';
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if the browser has AC3 support
|
||||
*/
|
||||
export function hasAc3Support(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean {
|
||||
if (context.$browser.isTv()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!videoTestElement
|
||||
.canPlayType('audio/mp4; codecs="ac-3"')
|
||||
.replace(/no/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if the browser has AC3 support
|
||||
*/
|
||||
export function hasAc3InHlsSupport(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean {
|
||||
if (context.$browser.isTizen() || context.$browser.isWebOS()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (videoTestElement.canPlayType) {
|
||||
return !!(
|
||||
videoTestElement
|
||||
.canPlayType('application/x-mpegurl; codecs="avc1.42E01E, ac-3"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType(
|
||||
'application/vnd.apple.mpegURL; codecs="avc1.42E01E, ac-3"'
|
||||
)
|
||||
.replace(/no/, '')
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browser has EAC3 support
|
||||
*/
|
||||
export function hasEac3Support(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean {
|
||||
if (context.$browser.isTv()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!videoTestElement
|
||||
.canPlayType('audio/mp4; codecs="ec-3"')
|
||||
.replace(/no/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browser has AAC support
|
||||
*/
|
||||
export function hasAacSupport(videoTestElement: HTMLVideoElement): boolean {
|
||||
return !!videoTestElement
|
||||
.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"')
|
||||
.replace(/no/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @returns {boolean} Determines if browser has MP2 support
|
||||
*/
|
||||
export function hasMp2AudioSupport(context: Context): boolean {
|
||||
return context.$browser.isTv();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browser has Mp3 support
|
||||
*/
|
||||
export function hasMp3AudioSupport(
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean {
|
||||
return !!(
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="avc1.640029, mp4a.69"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="avc1.640029, mp4a.6B"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="avc1.640029, mp3"')
|
||||
.replace(/no/, '')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines DTS audio support
|
||||
*
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browserr has DTS audio support
|
||||
*/
|
||||
export function hasDtsSupport(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean | string {
|
||||
// DTS audio not supported in 2018 models (Tizen 4.0)
|
||||
if (
|
||||
context.$browser.isTizen4() ||
|
||||
context.$browser.isTizen5() ||
|
||||
context.$browser.isTizen55()
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
context.$browser.isTv() ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="dts-"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement.canPlayType('video/mp4; codecs="dts+"').replace(/no/, '')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {string[]} Array of supported MP4 audio codecs
|
||||
*/
|
||||
export function getSupportedMP4AudioCodecs(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
|
||||
if (hasAacSupport(videoTestElement)) {
|
||||
codecs.push('aac');
|
||||
}
|
||||
|
||||
if (hasMp3AudioSupport(videoTestElement)) {
|
||||
codecs.push('mp3');
|
||||
}
|
||||
|
||||
if (hasAc3Support(context, videoTestElement)) {
|
||||
codecs.push('ac3');
|
||||
|
||||
if (hasEac3Support(context, videoTestElement)) {
|
||||
codecs.push('eac3');
|
||||
}
|
||||
}
|
||||
|
||||
if (hasMp2AudioSupport(context)) {
|
||||
codecs.push('mp2');
|
||||
}
|
||||
|
||||
if (hasDtsSupport(context, videoTestElement)) {
|
||||
codecs.push('dca');
|
||||
codecs.push('dts');
|
||||
}
|
||||
|
||||
if (context.$browser.isTizen() || context.$browser.isWebOS()) {
|
||||
codecs.push('pcm_s16le');
|
||||
codecs.push('pcm_s24le');
|
||||
}
|
||||
|
||||
if (context.$browser.isTizen()) {
|
||||
codecs.push('aac_latm');
|
||||
}
|
||||
|
||||
if (getSupportedAudioCodecs(context, 'opus')) {
|
||||
codecs.push('opus');
|
||||
}
|
||||
|
||||
if (getSupportedAudioCodecs(context, 'flac')) {
|
||||
codecs.push('flac');
|
||||
}
|
||||
|
||||
if (getSupportedAudioCodecs(context, 'alac')) {
|
||||
codecs.push('alac');
|
||||
}
|
||||
|
||||
if (hasVp8Support || context.$browser.isTizen()) {
|
||||
codecs.push('vorbis');
|
||||
}
|
||||
|
||||
return codecs;
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
import { Context } from '@nuxt/types';
|
||||
|
||||
/**
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browser has H264 support
|
||||
*/
|
||||
export function hasH264Support(videoTestElement: HTMLVideoElement): boolean {
|
||||
return !!(
|
||||
videoTestElement.canPlayType &&
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')
|
||||
.replace(/no/, '')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browser has H265 support
|
||||
*/
|
||||
export function hasH265Support(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean {
|
||||
if (context.$browser.isTv()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!(
|
||||
videoTestElement.canPlayType &&
|
||||
(videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hvc1.1.L120"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hev1.1.L120"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hvc1.1.0.L120"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hev1.1.0.L120"')
|
||||
.replace(/no/, ''))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browser has HEVC Support
|
||||
*/
|
||||
export function hasHevcSupport(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean {
|
||||
if (context.$browser.isTv()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!(
|
||||
!!videoTestElement.canPlayType &&
|
||||
(videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hvc1.1.L120"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hev1.1.L120"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hvc1.1.0.L120"')
|
||||
.replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('video/mp4; codecs="hev1.1.0.L120"')
|
||||
.replace(/no/, ''))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browser has AV1 support
|
||||
*/
|
||||
export function hasAv1Support(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean {
|
||||
if (context.$browser.isTizen() && context.$browser.isTizen55()) {
|
||||
return true;
|
||||
} else if (context.$browser.isWebOS5() && window.outerHeight >= 2160) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!(
|
||||
videoTestElement.canPlayType &&
|
||||
videoTestElement
|
||||
.canPlayType('video/webm; codecs="av01.0.15M.10"')
|
||||
.replace(/no/, '')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browser has VC1 support
|
||||
*/
|
||||
function hasVc1Support(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean {
|
||||
return !!(
|
||||
context.$browser.isTv() ||
|
||||
videoTestElement.canPlayType('video/mp4; codecs="vc-1"').replace(/no/, '')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browser has VP8 support
|
||||
*/
|
||||
export function hasVp8Support(videoTestElement: HTMLVideoElement): boolean {
|
||||
return !!(
|
||||
videoTestElement.canPlayType &&
|
||||
videoTestElement.canPlayType('video/webm; codecs="vp8"').replace(/no/, '')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if browser has VP9 support
|
||||
*/
|
||||
export function hasVp9Support(videoTestElement: HTMLVideoElement): boolean {
|
||||
return !!(
|
||||
videoTestElement.canPlayType &&
|
||||
videoTestElement.canPlayType('video/webm; codecs="vp9"').replace(/no/, '')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the platform for the codecs suppers in an MP4 container.
|
||||
*
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {string[]} Array of codec identifiers.
|
||||
*/
|
||||
export function getSupportedMP4VideoCodecs(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
|
||||
if (hasH264Support(videoTestElement)) {
|
||||
codecs.push('h264');
|
||||
}
|
||||
|
||||
if (hasHevcSupport(context, videoTestElement)) {
|
||||
// Safari is lying on HDR and 60fps videos, use fMP4 instead
|
||||
if (!context.$browser.isApple()) {
|
||||
codecs.push('hevc');
|
||||
}
|
||||
}
|
||||
|
||||
if (context.$browser.isTv()) {
|
||||
codecs.push('mpeg2video');
|
||||
}
|
||||
|
||||
if (hasVc1Support(context, videoTestElement)) {
|
||||
codecs.push('vc1');
|
||||
}
|
||||
|
||||
if (context.$browser.isTizen()) {
|
||||
codecs.push('msmpeg4v2');
|
||||
}
|
||||
|
||||
if (hasVp8Support(videoTestElement)) {
|
||||
codecs.push('vp8');
|
||||
}
|
||||
|
||||
if (hasVp9Support(videoTestElement)) {
|
||||
codecs.push('vp9');
|
||||
}
|
||||
|
||||
if (hasAv1Support(context, videoTestElement)) {
|
||||
codecs.push('av1');
|
||||
}
|
||||
|
||||
return codecs;
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
import { Context } from '@nuxt/types';
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if the browser can play native Hls
|
||||
*/
|
||||
export function canPlayNativeHls(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean {
|
||||
if (context.$browser.isTizen()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
videoTestElement.canPlayType('application/x-mpegURL').replace(/no/, '') ||
|
||||
videoTestElement
|
||||
.canPlayType('application/vnd.apple.mpegURL')
|
||||
.replace(/no/, '')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @returns {boolean} Determines if the browser can play Hls with Media Source Extensions
|
||||
*/
|
||||
export function canPlayHlsWithMSE(context: Context): boolean {
|
||||
return context.$browser.supportsMediaSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {boolean} Determines if the browser can play Mkvs
|
||||
*/
|
||||
export function hasMkvSupport(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): boolean {
|
||||
if (context.$browser.isTv()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
videoTestElement.canPlayType('video/x-matroska').replace(/no/, '') ||
|
||||
videoTestElement.canPlayType('video/mkv').replace(/no/, '')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (context.$browser.isEdge()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
import { Context } from '@nuxt/types';
|
||||
import {
|
||||
hasAacSupport,
|
||||
hasAc3InHlsSupport,
|
||||
hasAc3Support,
|
||||
hasEac3Support,
|
||||
hasMp3AudioSupport
|
||||
} from './mp4AudioFormats';
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {string[]} List of supported Ts audio codecs
|
||||
*/
|
||||
export function getSupportedTsAudioCodecs(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
|
||||
if (hasAacSupport(videoTestElement)) {
|
||||
codecs.push('aac');
|
||||
}
|
||||
|
||||
if (hasMp3AudioSupport(videoTestElement)) {
|
||||
codecs.push('mp3');
|
||||
}
|
||||
|
||||
if (hasAc3Support(context, videoTestElement)) {
|
||||
if (hasAc3InHlsSupport(context, videoTestElement)) {
|
||||
codecs.push('ac3');
|
||||
|
||||
if (hasEac3Support(context, videoTestElement)) {
|
||||
codecs.push('eac3');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return codecs;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { hasH264Support } from './mp4VideoFormats';
|
||||
|
||||
/**
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {string[]} List of supported ts video codecs
|
||||
*/
|
||||
export function getSupportedTsVideoCodecs(
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
|
||||
if (hasH264Support(videoTestElement)) {
|
||||
codecs.push('h264');
|
||||
}
|
||||
|
||||
return codecs;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
import { Context } from '@nuxt/types';
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {string[]} An array of supported codecs
|
||||
*/
|
||||
export function getSupportedWebMAudioCodecs(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
|
||||
codecs.push('vorbis');
|
||||
|
||||
if (
|
||||
!context.$browser.isWebOS() &&
|
||||
videoTestElement.canPlayType('audio/ogg; codecs="opus"').replace(/no/, '')
|
||||
) {
|
||||
codecs.push('opus');
|
||||
}
|
||||
|
||||
return codecs;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import { Context } from '@nuxt/types';
|
||||
import { hasAv1Support, hasVp8Support, hasVp9Support } from './mp4VideoFormats';
|
||||
|
||||
/**
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {string[]} An array of supported codecs
|
||||
*/
|
||||
export function getSupportedWebMVideoCodecs(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
|
||||
if (hasVp8Support(videoTestElement)) {
|
||||
codecs.push('vp8');
|
||||
}
|
||||
|
||||
if (hasVp9Support(videoTestElement)) {
|
||||
codecs.push('vp9');
|
||||
}
|
||||
|
||||
if (hasAv1Support(context, videoTestElement)) {
|
||||
codecs.push('av1');
|
||||
}
|
||||
|
||||
return codecs;
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { DlnaProfileType, ResponseProfile } from '@jellyfin/client-axios';
|
||||
|
||||
/**
|
||||
* Returns a valid ResponseProfile for the current platform.
|
||||
*
|
||||
* @returns {Array<ResponseProfile>} An array of subtitle profiles for the current platform.
|
||||
*/
|
||||
export function getResponseProfiles(): Array<ResponseProfile> {
|
||||
const ResponseProfiles = [];
|
||||
|
||||
ResponseProfiles.push({
|
||||
Type: DlnaProfileType.Video,
|
||||
Container: 'm4v',
|
||||
MimeType: 'video/mp4'
|
||||
});
|
||||
|
||||
return ResponseProfiles;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
import {
|
||||
SubtitleDeliveryMethod,
|
||||
SubtitleProfile
|
||||
} from '@jellyfin/client-axios';
|
||||
|
||||
/**
|
||||
* Returns a valid SubtitleProfile for the current platform.
|
||||
*
|
||||
* @returns {Array<SubtitleProfile>} An array of subtitle profiles for the current platform.
|
||||
*/
|
||||
export function getSubtitleProfiles(): Array<SubtitleProfile> {
|
||||
const SubtitleProfiles: Array<SubtitleProfile> = [];
|
||||
|
||||
SubtitleProfiles.push({
|
||||
Format: 'vtt',
|
||||
Method: SubtitleDeliveryMethod.External
|
||||
});
|
||||
|
||||
SubtitleProfiles.push({
|
||||
Format: 'ass',
|
||||
Method: SubtitleDeliveryMethod.External
|
||||
});
|
||||
|
||||
SubtitleProfiles.push({
|
||||
Format: 'ssa',
|
||||
Method: SubtitleDeliveryMethod.External
|
||||
});
|
||||
|
||||
return SubtitleProfiles;
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
import {
|
||||
DlnaProfileType,
|
||||
EncodingContext,
|
||||
TranscodingProfile
|
||||
} from '@jellyfin/client-axios';
|
||||
import { Context } from '@nuxt/types';
|
||||
import { getSupportedAudioCodecs } from './helpers/audioFormats';
|
||||
import { getSupportedMP4AudioCodecs } from './helpers/mp4AudioFormats';
|
||||
import {
|
||||
getSupportedMP4VideoCodecs,
|
||||
hasVp8Support
|
||||
} from './helpers/mp4VideoFormats';
|
||||
import {
|
||||
canPlayNativeHls,
|
||||
canPlayHlsWithMSE,
|
||||
hasMkvSupport
|
||||
} from './helpers/transcodingFormats';
|
||||
import { getSupportedTsAudioCodecs } from './helpers/tsAudioFormats';
|
||||
import { getSupportedTsVideoCodecs } from './helpers/tsVideoFormats';
|
||||
|
||||
/**
|
||||
* Returns a valid TranscodingProfile for the current platform.
|
||||
*
|
||||
* @param {Context} context - Nuxt context
|
||||
* @param {HTMLVideoElement} videoTestElement - A HTML video element for testing codecs
|
||||
* @returns {Array<TranscodingProfile>} An array of transcoding profiles for the current platform.
|
||||
*/
|
||||
export function getTranscodingProfiles(
|
||||
context: Context,
|
||||
videoTestElement: HTMLVideoElement
|
||||
): Array<TranscodingProfile> {
|
||||
const TranscodingProfiles: TranscodingProfile[] = [];
|
||||
const physicalAudioChannels = context.$browser.isTv() ? 6 : 2;
|
||||
|
||||
const hlsBreakOnNonKeyFrames = !!(
|
||||
context.$browser.isApple() ||
|
||||
(context.$browser.isEdge() && !context.$browser.isChromiumBased()) ||
|
||||
!canPlayNativeHls(context, videoTestElement)
|
||||
);
|
||||
|
||||
const mp4AudioCodecs = getSupportedMP4AudioCodecs(context, videoTestElement);
|
||||
const mp4VideoCodecs = getSupportedMP4VideoCodecs(context, videoTestElement);
|
||||
const canPlayHls =
|
||||
canPlayNativeHls(context, videoTestElement) || canPlayHlsWithMSE(context);
|
||||
|
||||
if (canPlayHls) {
|
||||
TranscodingProfiles.push({
|
||||
// hlsjs, edge, and android all seem to require ts container
|
||||
Container:
|
||||
!canPlayNativeHls(context, videoTestElement) ||
|
||||
(context.$browser.isEdge() && !context.$browser.isChromiumBased()) ||
|
||||
context.$browser.isAndroid()
|
||||
? 'ts'
|
||||
: 'aac',
|
||||
Type: DlnaProfileType.Audio,
|
||||
AudioCodec: 'aac',
|
||||
Context: EncodingContext.Streaming,
|
||||
Protocol: 'hls',
|
||||
MaxAudioChannels: physicalAudioChannels.toString(),
|
||||
MinSegments: context.$browser.isApple() ? 2 : 1,
|
||||
BreakOnNonKeyFrames: hlsBreakOnNonKeyFrames
|
||||
});
|
||||
}
|
||||
|
||||
['aac', 'mp3', 'opus', 'wav']
|
||||
.filter((format) => getSupportedAudioCodecs(context, format))
|
||||
.forEach((audioFormat) => {
|
||||
TranscodingProfiles.push({
|
||||
Container: audioFormat,
|
||||
Type: DlnaProfileType.Audio,
|
||||
AudioCodec: audioFormat,
|
||||
Context: EncodingContext.Streaming,
|
||||
Protocol: 'http',
|
||||
MaxAudioChannels: physicalAudioChannels.toString()
|
||||
});
|
||||
});
|
||||
|
||||
const hlsInTsVideoCodecs = getSupportedTsVideoCodecs(videoTestElement);
|
||||
const hlsInTsAudioCodecs = getSupportedTsAudioCodecs(
|
||||
context,
|
||||
videoTestElement
|
||||
);
|
||||
|
||||
if (canPlayHls) {
|
||||
// TODO
|
||||
// Disabled for now as HLS.js has troubles seeking in it
|
||||
// We should enable it for platforms supporting it natively
|
||||
|
||||
// const hlsInFmp4VideoCodecs = getSupportedFmp4VideoCodecs(
|
||||
// context,
|
||||
// videoTestElement
|
||||
// );
|
||||
// const hlsInFmp4AudioCodecs = getSupportedFmp4AudioCodecs(
|
||||
// context,
|
||||
// videoTestElement
|
||||
// );
|
||||
|
||||
// if (hlsInFmp4VideoCodecs.length && hlsInFmp4AudioCodecs.length) {
|
||||
// TranscodingProfiles.push({
|
||||
// Container: 'mp4',
|
||||
// Type: DlnaProfileType.Video,
|
||||
// AudioCodec: hlsInFmp4AudioCodecs.join(','),
|
||||
// VideoCodec: hlsInFmp4VideoCodecs.join(','),
|
||||
// Context: EncodingContext.Streaming,
|
||||
// Protocol: 'hls',
|
||||
// MaxAudioChannels: physicalAudioChannels.toString(),
|
||||
// MinSegments: context.$browser.isApple() ? 2 : 1,
|
||||
// BreakOnNonKeyFrames: hlsBreakOnNonKeyFrames
|
||||
// });
|
||||
// }
|
||||
|
||||
if (hlsInTsVideoCodecs.length && hlsInTsAudioCodecs.length) {
|
||||
TranscodingProfiles.push({
|
||||
Container: 'ts',
|
||||
Type: DlnaProfileType.Video,
|
||||
AudioCodec: hlsInTsAudioCodecs.join(','),
|
||||
VideoCodec: hlsInTsVideoCodecs.join(','),
|
||||
Context: EncodingContext.Streaming,
|
||||
Protocol: 'hls',
|
||||
MaxAudioChannels: physicalAudioChannels.toString(),
|
||||
MinSegments: context.$browser.isApple() ? 2 : 1,
|
||||
BreakOnNonKeyFrames: hlsBreakOnNonKeyFrames
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (hasMkvSupport(context, videoTestElement) && !context.$browser.isTizen()) {
|
||||
TranscodingProfiles.push({
|
||||
Container: 'mkv',
|
||||
Type: DlnaProfileType.Video,
|
||||
AudioCodec: mp4AudioCodecs.join(','),
|
||||
VideoCodec: mp4VideoCodecs.join(','),
|
||||
Context: EncodingContext.Streaming,
|
||||
MaxAudioChannels: physicalAudioChannels.toString(),
|
||||
CopyTimestamps: true
|
||||
});
|
||||
}
|
||||
|
||||
if (hasVp8Support(videoTestElement)) {
|
||||
TranscodingProfiles.push({
|
||||
Container: 'webm',
|
||||
Type: DlnaProfileType.Video,
|
||||
AudioCodec: 'vorbis',
|
||||
VideoCodec: 'vpx',
|
||||
Context: EncodingContext.Streaming,
|
||||
Protocol: 'http',
|
||||
// If audio transcoding is needed, limit channels to number of physical audio channels
|
||||
// Trying to transcode to 5 channels when there are only 2 speakers generally does not sound good
|
||||
MaxAudioChannels: physicalAudioChannels.toString()
|
||||
});
|
||||
}
|
||||
|
||||
return TranscodingProfiles;
|
||||
}
|
Loading…
Reference in New Issue
Block a user