diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 21a711bd..06f5b345 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -22,7 +22,7 @@ import { PeopleListComponent } from './components/people-list/people-list.compon import { BufferToWidthPipe, FormatTimePipe, - PlayerComponent, + PlayerComponent, SupportedButtonPipe, VolumeToButtonPipe } from "./pages/player/player.component"; import { SearchComponent } from './pages/search/search.component'; @@ -67,7 +67,8 @@ import { MatBadgeModule } from "@angular/material/badge"; ShowGridComponent, FormatTimePipe, BufferToWidthPipe, - VolumeToButtonPipe + VolumeToButtonPipe, + SupportedButtonPipe ], imports: [ BrowserModule, diff --git a/src/app/pages/player/playbackMethodDetector.ts b/src/app/pages/player/playbackMethodDetector.ts new file mode 100644 index 00000000..0e3482d8 --- /dev/null +++ b/src/app/pages/player/playbackMethodDetector.ts @@ -0,0 +1,155 @@ +import { detect } from "detect-browser"; +import { Track, WatchItem } from "../../models/watch-item"; + +export enum method +{ + direct = "Direct Play", + transmux = "Transmux", + transcode = "Transcode" +} + +export class SupportList +{ + container: boolean; + videoCodec: boolean; + audioCodec: boolean[]; + + getPlaybackMethod(): method + { + if (this.container) + { + if (this.videoCodec && this.audioCodec) + return method.direct; + return method.transcode; + } + + if (this.videoCodec && this.audioCodec) + return method.transmux; + return method.transcode; + } +} + +export function getWhatIsSupported(player: HTMLVideoElement, item: WatchItem): SupportList +{ + let supportList: SupportList = new SupportList(); + let browser = detect(); + + if (!browser) + { + supportList.container = false; + supportList.videoCodec = false; + supportList.audioCodec = item.audios.map(() => false); + } + else + { + supportList.container = containerIsSupported(player, item.container, browser.name) && item.audios.length <= 1; + supportList.videoCodec = videoCodecIsSupported(player, item.video.codec, browser.name); + supportList.audioCodec = item.audios.map((x: Track) => audioCodecIsSupported(player, x.codec, browser.name)); + } + return (supportList); +} + +function containerIsSupported(player: HTMLVideoElement, container: string, browser: string): boolean +{ + switch (container) + { + case "asf": + return browser == "tizen" || browser == "orsay" || browser == "edge"; + case "avi": + return browser == "tizen" || browser == "orsay" || browser == "edge"; + case "mpg": + case "mpeg": + return browser == "tizen" || browser == "orsay" || browser == "edge"; + case "flv": + return browser == "tizen" || browser == "orsay"; + case "3gp": + case "mts": + case "trp": + case "vob": + case "vro": + return browser == "tizen" || browser == "orsay"; + case "mov": + return browser == "tizen" || browser == "orsay" || browser == "edge" || browser == "chrome"; + case "m2ts": + return browser == "tizen" || browser == "orsay" || browser == "edge"; + case "wmv": + return browser == "tizen" || browser == "orsay" || browser == "edge"; + case "ts": + return browser == "tizen" || browser == "orsay" || browser == "edge"; + case "mp4": + case "m4v": + return true; + case "mkv": + if (browser == "tizen" || browser == "orsay" || browser == "chrome" || browser == "edge") + return true; + return !!(player.canPlayType("video/x-matroska") || player.canPlayType("video/mkv")); + + default: + return false; + } +} + +//SHOULD CHECK FOR DEPTH (8bits ok but 10bits unsupported for almost every browsers) +function videoCodecIsSupported(player: HTMLVideoElement, codec: string, browser: string): boolean +{ + switch (codec) + { + case "h264": + return !!player.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"'); + case "h265": + case "hevc": + if (browser == "tizen" || browser == "orsay" || browser == "xboxOne" || browser == "ios") + return true; + //SHOULD SUPPORT CHROMECAST ULTRA + // if (browser.chromecast) + // { + + // var isChromecastUltra = userAgent.indexOf('aarch64') !== -1; + // if (isChromecastUltra) + // { + // return true; + // } + // } + return !!player.canPlayType('video/hevc; codecs="hevc, aac"'); + case "mpeg2video": + return browser == "orsay" || browser == "tizen" || browser == "edge"; + case "vc1": + return browser == "orsay" || browser == "tizen" || browser == "edge"; + case "msmpeg4v2": + return browser == "orsay" || browser == "tizen"; + case "vp8": + return !!player.canPlayType('video/webm; codecs="vp8'); + case "vp9": + return !!player.canPlayType('video/webm; codecs="vp9"'); + case "vorbis": + return browser == "orsay" || browser == "tizen" || !!player.canPlayType('video/webm; codecs="vp8'); + default: + return false; + } +} + +//SHOULD CHECK FOR NUMBER OF AUDIO CHANNEL (2 ok but 5 not in some browsers) +function audioCodecIsSupported(player: HTMLVideoElement, codec: string, browser: string): boolean +{ + switch (codec) + { + case "mp3": + return !!player.canPlayType('video/mp4; codecs="avc1.640029, mp4a.69"') || + !!player.canPlayType('video/mp4; codecs="avc1.640029, mp4a.6B"'); + case "aac": + return !!player.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"'); + case "mp2": + return browser == "orsay" || browser == "tizen" || browser == "edge"; + case "pcm_s16le": + case "pcm_s24le": + return browser == "orsay" || browser == "tizen" || browser == "edge"; + case "aac_latm": + return browser == "orsay" || browser == "tizen"; + case "opus": + return !!player.canPlayType('audio/ogg; codecs="opus"'); + case "flac": + return browser == "orsay" || browser == "tizen" || browser == "edge"; + default: + return false; + } +} diff --git a/src/app/pages/player/player.component.html b/src/app/pages/player/player.component.html index f18a9299..7b3c5f58 100644 --- a/src/app/pages/player/player.component.html +++ b/src/app/pages/player/player.component.html @@ -37,25 +37,25 @@ Video Container: {{this.item.container}} - {{getSupportedFeature("container")}} + {{this.supportList | supportedButton: "container"}} Video Codec: {{this.item.video.codec}} - {{getSupportedFeature("video")}} + {{this.supportList | supportedButton: "video"}} Audio Codec: - {{this.item.audios[0].codec}} - {{getSupportedFeature("audio")}} + {{this.item.audios[this.selectedAudio].codec}} + {{this.supportList | supportedButton: "audio":this.selectedAudio}} Subtitle Codec: - {{this.selectedSubtitle ? this.selectedSubtitle.codec : "none"}} - {{getSupportedFeature("subtitle")}} + {{this.selectedSubtitle != -1 ? this.item.subtitles[this.selectedSubtitle].codec : "none"}} + {{this.supportList | supportedButton: "subtitle"}} @@ -130,7 +130,8 @@
{{player.currentTime | formatTime: player.duration}} / {{player.duration | formatTime}}