@ngx-telly/plugin-vu-meter
Version:
Telly - Vu meter plugin
1 lines • 36.1 kB
Source Map (JSON)
{"version":3,"file":"ngx-telly-plugin-vu-meter.mjs","sources":["../../../../libs/plugin-vu-meter/src/lib/vu-meter.service.ts","../../../../libs/plugin-vu-meter/src/lib/components/telly-vu-meter/telly-vu-meter.component.ts","../../../../libs/plugin-vu-meter/src/lib/components/telly-vu-meter/telly-vu-meter.component.html","../../../../libs/plugin-vu-meter/src/lib/icons.ts","../../../../libs/plugin-vu-meter/src/lib/components/telly-vu-meter-toggle/telly-vu-meter-toggle.component.ts","../../../../libs/plugin-vu-meter/src/lib/components/telly-vu-meter-toggle/telly-vu-meter-toggle.component.html","../../../../libs/plugin-vu-meter/src/provider.ts","../../../../libs/plugin-vu-meter/src/ngx-telly-plugin-vu-meter.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Subject } from 'rxjs';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class VuMeterService {\n show$ = new BehaviorSubject<boolean>(false);\n reconfigure$ = new Subject<void>();\n\n on() {\n this.show$.next(true);\n }\n\n off() {\n this.show$.next(false);\n }\n\n toggle() {\n this.show$.next(!this.show$.value);\n }\n\n reconfigure() {\n this.reconfigure$.next();\n }\n\n isVisible() {\n return this.show$.value;\n }\n}\n","import {\n Component,\n HostBinding,\n inject,\n Input,\n OnChanges,\n OnDestroy,\n OnInit,\n signal,\n SimpleChanges,\n} from '@angular/core';\nimport { VuMeterService } from '../../vu-meter.service';\nimport { PlayerComponent } from '@ngx-telly/player';\nimport { eventType, VideoEvent } from '@ngx-telly/player/core';\nimport { filter, map, skip, Subscription, tap } from 'rxjs';\nimport { AsyncPipe } from '@angular/common';\n\nexport interface Level {\n channel: string;\n rms: number;\n db: number;\n normalized: number;\n peak: number;\n}\n\ninterface AudioAnalysisState {\n isAnalyzing: boolean;\n analysisTimeout?: ReturnType<typeof setTimeout>;\n peakHoldValues: number[];\n peakHoldTimers: number[];\n}\n\ninterface AudioNodes {\n context?: AudioContext;\n source?: MediaElementAudioSourceNode | MediaStreamAudioSourceNode;\n splitter?: ChannelSplitterNode;\n analyzers: AnalyserNode[];\n dataArrays: Float32Array<ArrayBuffer>[];\n}\n\n@Component({\n selector: 'telly-vu-meter',\n imports: [AsyncPipe],\n templateUrl: './telly-vu-meter.component.html',\n styleUrl: './telly-vu-meter.component.css',\n})\nexport class TellyVuMeterComponent implements OnInit, OnDestroy, OnChanges {\n @HostBinding('style.display')\n display = 'none';\n\n @Input() fftSize = 1024;\n @Input() channelCount = 2;\n @Input() channelNames: string[] = [];\n @Input() peakHoldTime = 300;\n @Input() peakDecayRate = 0.1;\n @Input() peakAccelerationFactor = 4;\n @Input() updateRateMs = 40;\n\n readonly service = inject(VuMeterService);\n readonly player = inject(PlayerComponent);\n\n private readonly subscription = new Subscription();\n private readonly audioNodes: AudioNodes = {\n context: undefined,\n splitter: undefined,\n source: undefined,\n analyzers: [],\n dataArrays: [],\n };\n private readonly analysisState: AudioAnalysisState = {\n isAnalyzing: false,\n peakHoldValues: [],\n peakHoldTimers: [],\n };\n\n private gestureAbortController?: AbortController;\n private reconfigureTimeout?: ReturnType<typeof setTimeout>;\n private destroyed = false;\n\n readonly levels = signal<Level[]>([]);\n readonly initializing = signal(false);\n readonly reconfiguring = signal(false);\n readonly showVolumeWarning = signal(false);\n\n ngOnInit(): void {\n this.setupVisibilitySubscription();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['channelCount'] && !changes['channelCount'].isFirstChange()) {\n this.updateChannelCount(changes['channelCount'].currentValue);\n }\n }\n\n ngOnDestroy(): void {\n this.destroyed = true;\n this.service.off();\n\n if (this.gestureAbortController) {\n this.gestureAbortController.abort();\n }\n\n if (this.reconfigureTimeout) {\n clearTimeout(this.reconfigureTimeout);\n }\n\n this.stopAnalysis();\n this.disconnectAudioGraph();\n this.cleanupAudioContext();\n this.subscription.unsubscribe();\n }\n\n private setupVisibilitySubscription(): void {\n this.subscription.add(\n this.service.show$\n .pipe(\n skip(1),\n tap((show) => this.player.media.indicate(`VU Meter ${show ? 'ON' : 'OFF'}`)),\n tap((show) => {\n if (show) {\n this.initializeAudioAndStartAnalysis();\n } else {\n this.stopAnalysis();\n this.disconnectAudioGraph();\n }\n }),\n map((show) => (show ? 'flex' : 'none'))\n )\n .subscribe((display) => (this.display = display))\n );\n\n this.subscription.add(this.service.reconfigure$.subscribe(() => this.reconfigure()));\n\n // when playback resumes after ending, the captureStream audio tracks are\n // replaced — reconnect the source so the analyzers see fresh data\n this.subscription.add(\n this.player.media.events\n .pipe(\n eventType([VideoEvent.Playing]),\n filter(() => this.analysisState.isAnalyzing && this.usesCaptureStream())\n )\n .subscribe(() => this.reconnectSource())\n );\n }\n\n private reconfigure() {\n this.reconfiguring.set(true);\n this.stopAnalysis();\n this.disconnectAudioGraph();\n\n this.reconfigureTimeout = setTimeout(() => {\n this.reconfigureTimeout = undefined;\n this.reconfiguring.set(false);\n this.initializeAudioAndStartAnalysis();\n }, 1000);\n }\n\n private updateChannelCount(newCount: number): void {\n this.channelCount = newCount;\n\n if (this.audioNodes.source && this.audioNodes.context) {\n const wasAnalyzing = this.analysisState.isAnalyzing;\n this.stopAnalysis();\n this.disconnectAudioGraph();\n\n if (wasAnalyzing) {\n this.connectAudioGraphAndStartAnalysis();\n }\n }\n }\n\n private initializeAudioAndStartAnalysis(): void {\n if (this.destroyed) return;\n\n if (!this.audioNodes.context) {\n this.initializing.set(true);\n this.initializeAudioContext()\n .then(() => {\n if (!this.destroyed) {\n this.connectAudioGraphAndStartAnalysis();\n }\n })\n .catch((error) => {\n if (error.name !== 'AbortError') {\n console.error('Failed to initialize audio for VU meter:', error);\n }\n })\n .finally(() => this.initializing.set(false));\n } else {\n this.connectAudioGraphAndStartAnalysis();\n }\n }\n\n private async initializeAudioContext(): Promise<void> {\n if (this.audioNodes.context) {\n // resume a suspended context (e.g. created before user gesture)\n if (this.audioNodes.context.state === 'suspended') {\n await this.audioNodes.context.resume();\n }\n return;\n }\n\n this.audioNodes.context = new AudioContext();\n\n // if the context is suspended due to autoplay policy, wait for user gesture\n if (this.audioNodes.context.state === 'suspended') {\n await this.waitForUserGesture();\n await this.audioNodes.context.resume();\n }\n\n if (!this.audioNodes.source && this.audioNodes.context) {\n const mediaEl = this.player.video.nativeElement as HTMLVideoElement;\n\n try {\n if (typeof (mediaEl as any).captureStream === 'function') {\n const stream: MediaStream = (mediaEl as any).captureStream();\n\n // wait for audio tracks if none are available yet\n if (stream.getAudioTracks().length === 0) {\n await this.waitForAudioTrack(stream);\n }\n\n if (this.destroyed) return;\n\n this.audioNodes.source = this.audioNodes.context.createMediaStreamSource(stream);\n } else {\n this.audioNodes.source = this.audioNodes.context.createMediaElementSource(mediaEl);\n this.audioNodes.source.connect(this.audioNodes.context.destination);\n this.showVolumeWarning.set(true);\n }\n } catch (err) {\n if ((err as DOMException)?.name !== 'AbortError') {\n console.error('Error initializing audio source:', err);\n }\n }\n }\n }\n\n private waitForUserGesture(): Promise<void> {\n const controller = new AbortController();\n this.gestureAbortController = controller;\n const { signal } = controller;\n\n return new Promise((resolve, reject) => {\n if (signal.aborted) {\n reject(signal.reason);\n return;\n }\n\n const events = ['click', 'touchstart', 'keydown'] as const;\n const handler = () => {\n this.gestureAbortController = undefined;\n resolve();\n };\n events.forEach((e) => document.addEventListener(e, handler, { once: true, signal }));\n\n signal.addEventListener('abort', () => {\n reject(new DOMException('Aborted', 'AbortError'));\n });\n });\n }\n\n private waitForAudioTrack(stream: MediaStream): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.destroyed) {\n reject(new DOMException('Aborted', 'AbortError'));\n return;\n }\n\n const onTrack = (event: MediaStreamTrackEvent) => {\n if (event.track.kind === 'audio') {\n stream.removeEventListener('addtrack', onTrack);\n resolve();\n }\n };\n\n stream.addEventListener('addtrack', onTrack);\n\n // also resolve if audio tracks appear before the listener fires\n const checkInterval = setInterval(() => {\n if (this.destroyed) {\n clearInterval(checkInterval);\n stream.removeEventListener('addtrack', onTrack);\n reject(new DOMException('Aborted', 'AbortError'));\n return;\n }\n if (stream.getAudioTracks().length > 0) {\n clearInterval(checkInterval);\n stream.removeEventListener('addtrack', onTrack);\n resolve();\n }\n }, 200);\n });\n }\n\n private usesCaptureStream(): boolean {\n return this.audioNodes.source instanceof MediaStreamAudioSourceNode;\n }\n\n private reconnectSource(): void {\n if (!this.audioNodes.context || !this.usesCaptureStream()) return;\n\n const mediaEl = this.player.video.nativeElement as HTMLVideoElement;\n const stream: MediaStream = (mediaEl as any).captureStream();\n\n if (stream.getAudioTracks().length === 0) return;\n\n // tear down old graph and source, rebuild with fresh stream\n this.stopAnalysis();\n this.disconnectAudioGraph();\n\n if (this.audioNodes.source) {\n this.audioNodes.source.disconnect();\n }\n\n this.audioNodes.source = this.audioNodes.context.createMediaStreamSource(stream);\n this.connectAudioGraphAndStartAnalysis();\n }\n\n private connectAudioGraphAndStartAnalysis(): void {\n if (!this.audioNodes.context || !this.audioNodes.source) {\n console.warn('Audio context or source not initialized');\n return;\n }\n\n this.buildAudioGraph();\n this.startAnalysis();\n }\n\n private buildAudioGraph(): void {\n if (!this.audioNodes.context || !this.audioNodes.source) return;\n\n this.audioNodes.splitter = this.audioNodes.context.createChannelSplitter(this.channelCount);\n\n this.audioNodes.analyzers = Array(this.channelCount)\n .fill(0)\n .map(() => {\n const analyzer = this.audioNodes.context!.createAnalyser();\n analyzer.fftSize = this.fftSize;\n analyzer.smoothingTimeConstant = 0.8;\n return analyzer;\n });\n\n this.audioNodes.source.connect(this.audioNodes.splitter);\n this.audioNodes.analyzers.forEach((analyzer, i) => {\n this.audioNodes.splitter!.connect(analyzer, i);\n });\n\n this.audioNodes.dataArrays = this.audioNodes.analyzers.map((analyzer) => new Float32Array(analyzer.fftSize));\n }\n\n private startAnalysis(): void {\n if (this.analysisState.isAnalyzing) {\n return;\n }\n\n this.analysisState.isAnalyzing = true;\n this.analysisState.peakHoldValues = new Array(this.channelCount).fill(0);\n this.analysisState.peakHoldTimers = new Array(this.channelCount).fill(0);\n\n const channelNames = this.getChannelNames(this.channelCount);\n\n this.runAnalysisLoop(channelNames);\n }\n\n private runAnalysisLoop(channelNames: string[]): void {\n if (!this.analysisState.isAnalyzing) {\n return;\n }\n\n this.audioNodes.analyzers.forEach((analyzer, i) => {\n analyzer.getFloatTimeDomainData(this.audioNodes.dataArrays[i]);\n });\n\n const levels = this.audioNodes.dataArrays.map((dataArray, i) =>\n this.calculateChannelLevel(dataArray, channelNames[i], i)\n );\n\n this.levels.set(levels);\n\n this.analysisState.analysisTimeout = setTimeout(() => this.runAnalysisLoop(channelNames), this.updateRateMs);\n }\n\n private calculateChannelLevel(dataArray: Float32Array<ArrayBuffer>, channelName: string, channelIndex: number): Level {\n let sumSquares = 0;\n for (let i = 0; i < dataArray.length; i++) {\n sumSquares += dataArray[i] * dataArray[i];\n }\n\n const rms = Math.sqrt(sumSquares / dataArray.length);\n const db = Math.round(20 * Math.log10(Math.max(rms, 0.0000001)));\n const normalized = Math.max(0, Math.min(1, (db + 60) / 60));\n\n const peak = this.updatePeakHold(normalized, channelIndex);\n\n return {\n channel: channelName,\n rms,\n db,\n normalized,\n peak,\n };\n }\n\n private updatePeakHold(currentLevel: number, channelIndex: number): number {\n if (currentLevel > this.analysisState.peakHoldValues[channelIndex]) {\n this.analysisState.peakHoldValues[channelIndex] = currentLevel;\n this.analysisState.peakHoldTimers[channelIndex] = Date.now();\n } else {\n const timeSinceLastPeak = Date.now() - this.analysisState.peakHoldTimers[channelIndex];\n\n if (timeSinceLastPeak > this.peakHoldTime) {\n const decayTime = timeSinceLastPeak - this.peakHoldTime;\n const decaySeconds = decayTime / 1000;\n\n const smoothingFactor = Math.min(decaySeconds, 1);\n const currentDecayRate =\n this.peakDecayRate * Math.pow(this.peakAccelerationFactor, decaySeconds) * smoothingFactor;\n\n this.analysisState.peakHoldValues[channelIndex] = Math.max(\n 0,\n this.analysisState.peakHoldValues[channelIndex] - currentDecayRate\n );\n }\n }\n\n return this.analysisState.peakHoldValues[channelIndex];\n }\n\n private stopAnalysis(): void {\n this.analysisState.isAnalyzing = false;\n\n if (this.analysisState.analysisTimeout) {\n clearTimeout(this.analysisState.analysisTimeout);\n this.analysisState.analysisTimeout = undefined;\n }\n }\n\n private getChannelNames(count: number): string[] {\n if (this.channelNames.length) {\n return this.channelNames;\n }\n\n switch (count) {\n case 1:\n return ['M'];\n case 2:\n return ['L', 'R'];\n case 3:\n return ['L', 'R', 'LFE'];\n case 4:\n return ['FL', 'FR', 'SL', 'SR'];\n case 5:\n return ['FL', 'FR', 'C', 'SL', 'SR'];\n case 6:\n return ['FL', 'FR', 'C', 'LFE', 'SL', 'SR'];\n case 7:\n return ['FL', 'FR', 'C', 'LFE', 'SL', 'SR', 'BC'];\n case 8:\n return ['FL', 'FR', 'C', 'LFE', 'SL', 'SR', 'BL', 'BR'];\n default:\n return Array(count)\n .fill(0)\n .map((_, i) => `C${i + 1}`);\n }\n }\n\n private disconnectAudioGraph(): void {\n if (this.audioNodes.splitter) {\n this.audioNodes.analyzers.forEach((analyzer) => {\n analyzer.disconnect();\n });\n this.audioNodes.splitter.disconnect();\n }\n\n this.audioNodes.splitter = undefined;\n this.audioNodes.analyzers = [];\n this.audioNodes.dataArrays = [];\n }\n\n private cleanupAudioContext(): void {\n if (this.audioNodes.source && this.audioNodes.context) {\n this.audioNodes.source.disconnect();\n }\n\n if (this.audioNodes.context) {\n this.audioNodes.context.close().catch((err) => {\n console.error('Error closing audio context:', err);\n });\n }\n\n this.audioNodes.source = undefined;\n this.audioNodes.context = undefined;\n }\n}\n","@if ((service.show$ | async) && !reconfiguring() && !initializing() && levels().length) {\n <div class=\"vu-meter-container\">\n <div class=\"vu-meter-panel\">\n @if (showVolumeWarning()) {\n <div class=\"warning-icon\" title=\"VU meter levels follow player volume\">⚠️</div>\n }\n <div class=\"vu-meter-channels\">\n @for (level of levels(); track level.channel) {\n <div class=\"channel-meter\">\n <div class=\"channel-label\">{{ level.channel }}</div>\n <div class=\"meter-container\">\n <div class=\"meter-background\">\n <div class=\"meter-segment green\"></div>\n <div class=\"meter-segment green\"></div>\n <div class=\"meter-segment green\"></div>\n <div class=\"meter-segment green\"></div>\n <div class=\"meter-segment yellow\"></div>\n <div class=\"meter-segment yellow\"></div>\n <div class=\"meter-segment red\"></div>\n <div class=\"meter-segment red\"></div>\n </div>\n <div class=\"meter-background-full\"\n [style.clip-path]=\"'polygon(0 100%, 100% 100%, 100% ' + (100 - level.normalized * 100) + '%, 0 ' + (100 - level.normalized * 100) + '%)'\">\n <div class=\"meter-segment-full green\"></div>\n <div class=\"meter-segment-full green\"></div>\n <div class=\"meter-segment-full green\"></div>\n <div class=\"meter-segment-full green\"></div>\n <div class=\"meter-segment-full yellow\"></div>\n <div class=\"meter-segment-full yellow\"></div>\n <div class=\"meter-segment-full red\"></div>\n <div class=\"meter-segment-full red\"></div>\n </div>\n <div class=\"peak-indicator\"\n [style.bottom.%]=\"level.peak * 100\"\n [class.visible]=\"level.peak > 0.01\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n}\n\n@if (initializing() || reconfiguring()) {\n <div class=\"vu-meter-container\">\n <div class=\"vu-meter-panel\">\n <div class=\"vu-meter-channels\">\n <div class=\"channel-meter\">\n <div class=\"loading-info\">\n <div>Audio</div>\n <div>Loading</div>\n <div class=\"loading-animation\">\n <div class=\"spinner\"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n}\n","export const equalizer = 'M10,20H14V4H10V20M4,20H8V12H4V20M16,9V20H20V9H16Z';\nexport const gauge =\n 'M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,4A8,8 0 0,1 20,12C20,14.4 19,16.5 17.3,18C15.9,16.7 14,16 12,16C10,16 8.2,16.7 6.7,18C5,16.5 4,14.4 4,12A8,8 0 0,1 12,4M14,5.89C13.62,5.9 13.26,6.15 13.1,6.54L11.81,9.77L11.71,10C11,10.13 10.41,10.6 10.14,11.26C9.73,12.29 10.23,13.45 11.26,13.86C12.29,14.27 13.45,13.77 13.86,12.74C14.12,12.08 14,11.32 13.57,10.76L13.67,10.5L14.96,7.29L14.97,7.26C15.17,6.75 14.92,6.17 14.41,5.96C14.28,5.91 14.15,5.89 14,5.89M10,6A1,1 0 0,0 9,7A1,1 0 0,0 10,8A1,1 0 0,0 11,7A1,1 0 0,0 10,6M7,9A1,1 0 0,0 6,10A1,1 0 0,0 7,11A1,1 0 0,0 8,10A1,1 0 0,0 7,9M17,9A1,1 0 0,0 16,10A1,1 0 0,0 17,11A1,1 0 0,0 18,10A1,1 0 0,0 17,9';\n","import { Component, HostBinding, HostListener, inject, input } from '@angular/core';\nimport { VuMeterService } from '../../vu-meter.service';\nimport { gauge } from '../../icons';\n\n@Component({\n selector: 'telly-vu-meter-toggle',\n imports: [],\n templateUrl: './telly-vu-meter-toggle.component.html',\n styleUrl: './telly-vu-meter-toggle.component.css'\n})\nexport class TellyVuMeterToggleComponent {\n icon = input(gauge);\n size = input('1.4rem');\n\n service = inject(VuMeterService);\n\n @HostBinding('attr.tip') title = 'VU Meter';\n\n @HostListener('pointerdown')\n onClick(): void {\n this.service.toggle();\n }\n}\n","<svg\n viewBox=\"0 0 24 24\"\n [style.width]=\"size()\"\n>\n <path\n fill=\"white\"\n [attr.d]=\"icon()\"\n />\n</svg>\n\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { VuMeterService } from './lib/vu-meter.service';\n\nexport function provideTellyVuMeter(): EnvironmentProviders {\n return makeEnvironmentProviders([VuMeterService]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}