From 4f17aeee0149833df4b2f3a40792516cc1ddcd55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Bukowski?= Date: Tue, 7 Apr 2020 11:07:45 +0200 Subject: [PATCH] [expo-av] Add return type to loadAsync() (#7704) * [expo-av] Add return type to loadAsync() Authored-by: Alec Winograd --- CHANGELOG.md | 2 ++ build/AV.d.ts | 2 +- build/AV.js.map | 2 +- src/AV.ts | 6 +++++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a294c6841ff4..694fbda4fb7bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,3 +7,5 @@ ### 🎉 New features ### 🐛 Bug fixes + +- Fixed `Plaback.loadAsync()` return type. ([#7559](https://github.com/expo/expo/pull/7559) by [@awinograd](https://github.com/awinograd)) diff --git a/build/AV.d.ts b/build/AV.d.ts index d7e6d541d3c8c..c6ca6f0ecef92 100644 --- a/build/AV.d.ts +++ b/build/AV.d.ts @@ -71,7 +71,7 @@ export interface AV { } export interface Playback extends AV { playAsync(): Promise; - loadAsync(source: AVPlaybackSource, initialStatus: AVPlaybackStatusToSet, downloadAsync: boolean): any; + loadAsync(source: AVPlaybackSource, initialStatus: AVPlaybackStatusToSet, downloadAsync: boolean): Promise; unloadAsync(): Promise; playFromPositionAsync(positionMillis: number, tolerances?: { toleranceMillisBefore?: number; diff --git a/build/AV.js.map b/build/AV.js.map index 08a849139550a..2e7f8df128b99 100644 --- a/build/AV.js.map +++ b/build/AV.js.map @@ -1 +1 @@ -{"version":3,"file":"AV.js","sourceRoot":"","sources":["../src/AV.ts"],"names":[],"mappings":"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","sourcesContent":["import { Platform } from '@unimodules/core';\nimport { Asset } from 'expo-asset';\n\nimport ExponentAV from './ExponentAV';\n// TODO add:\n// disableFocusOnAndroid\n// audio routes (at least did become noisy on android)\n// pan\n// pitch\n// API to explicitly request audio focus / session\n// API to select stream type on Android\n// subtitles API\n\nexport enum PitchCorrectionQuality {\n Low = ExponentAV && ExponentAV.Qualities && ExponentAV.Qualities.Low,\n Medium = ExponentAV && ExponentAV.Qualities && ExponentAV.Qualities.Medium,\n High = ExponentAV && ExponentAV.Qualities && ExponentAV.Qualities.High,\n}\n\nexport type AVPlaybackSource =\n | number\n | {\n uri: string;\n overrideFileExtensionAndroid?: string;\n headers?: { [fieldName: string]: string };\n }\n | Asset;\n\nexport type AVPlaybackNativeSource = {\n uri: string;\n overridingExtension?: string | null;\n headers?: { [fieldName: string]: string };\n};\n\nexport type AVPlaybackStatus =\n | {\n isLoaded: false;\n androidImplementation?: string;\n error?: string; // populated exactly once when an error forces the object to unload\n }\n | {\n isLoaded: true;\n androidImplementation?: string;\n\n uri: string;\n\n progressUpdateIntervalMillis: number;\n durationMillis?: number;\n positionMillis: number;\n playableDurationMillis?: number;\n seekMillisToleranceBefore?: number;\n seekMillisToleranceAfter?: number;\n\n shouldPlay: boolean;\n isPlaying: boolean;\n isBuffering: boolean;\n\n rate: number;\n shouldCorrectPitch: boolean;\n volume: number;\n isMuted: boolean;\n isLooping: boolean;\n\n didJustFinish: boolean; // true exactly once when the track plays to finish\n };\n\nexport type AVPlaybackStatusToSet = {\n androidImplementation?: string;\n progressUpdateIntervalMillis?: number;\n positionMillis?: number;\n seekMillisToleranceBefore?: number;\n seekMillisToleranceAfter?: number;\n shouldPlay?: boolean;\n rate?: number;\n shouldCorrectPitch?: boolean;\n volume?: number;\n isMuted?: boolean;\n isLooping?: boolean;\n pitchCorrectionQuality?: PitchCorrectionQuality;\n};\n\nexport const _DEFAULT_PROGRESS_UPDATE_INTERVAL_MILLIS: number = 500;\nexport const _DEFAULT_INITIAL_PLAYBACK_STATUS: AVPlaybackStatusToSet = {\n positionMillis: 0,\n progressUpdateIntervalMillis: _DEFAULT_PROGRESS_UPDATE_INTERVAL_MILLIS,\n shouldPlay: false,\n rate: 1.0,\n shouldCorrectPitch: false,\n volume: 1.0,\n isMuted: false,\n isLooping: false,\n};\n\nexport function getNativeSourceFromSource(\n source?: AVPlaybackSource | null\n): AVPlaybackNativeSource | null {\n let uri: string | null = null;\n let overridingExtension: string | null = null;\n let headers: { [fieldName: string]: string } | undefined;\n\n if (typeof source === 'string' && Platform.OS === 'web') {\n return {\n uri: source,\n overridingExtension,\n headers,\n };\n }\n\n const asset: Asset | null = _getAssetFromPlaybackSource(source);\n if (asset != null) {\n uri = asset.localUri || asset.uri;\n } else if (\n source != null &&\n typeof source !== 'number' &&\n 'uri' in source &&\n typeof source.uri === 'string'\n ) {\n uri = source.uri;\n }\n\n if (uri == null) {\n return null;\n }\n\n if (\n source != null &&\n typeof source !== 'number' &&\n 'overrideFileExtensionAndroid' in source &&\n typeof source.overrideFileExtensionAndroid === 'string'\n ) {\n overridingExtension = source.overrideFileExtensionAndroid;\n }\n\n if (\n source != null &&\n typeof source !== 'number' &&\n 'headers' in source &&\n typeof source.headers === 'object'\n ) {\n headers = source.headers;\n }\n return { uri, overridingExtension, headers };\n}\n\nfunction _getAssetFromPlaybackSource(source?: AVPlaybackSource | null): Asset | null {\n if (source == null) {\n return null;\n }\n\n let asset: Asset | null = null;\n if (typeof source === 'number') {\n asset = Asset.fromModule(source);\n } else if (source instanceof Asset) {\n asset = source;\n }\n return asset;\n}\n\nexport function assertStatusValuesInBounds(status: AVPlaybackStatusToSet): void {\n if (typeof status.rate === 'number' && (status.rate < 0 || status.rate > 32)) {\n throw new RangeError('Rate value must be between 0.0 and 32.0');\n }\n if (typeof status.volume === 'number' && (status.volume < 0 || status.volume > 1)) {\n throw new RangeError('Volume value must be between 0.0 and 1.0');\n }\n}\n\nexport async function getNativeSourceAndFullInitialStatusForLoadAsync(\n source: AVPlaybackSource | null,\n initialStatus: AVPlaybackStatusToSet | null,\n downloadFirst: boolean\n): Promise<{\n nativeSource: AVPlaybackNativeSource;\n fullInitialStatus: AVPlaybackStatusToSet;\n}> {\n // Get the full initial status\n const fullInitialStatus: AVPlaybackStatusToSet =\n initialStatus == null\n ? _DEFAULT_INITIAL_PLAYBACK_STATUS\n : {\n ..._DEFAULT_INITIAL_PLAYBACK_STATUS,\n ...initialStatus,\n };\n assertStatusValuesInBounds(fullInitialStatus);\n\n if (typeof source === 'string' && Platform.OS === 'web') {\n return {\n nativeSource: {\n uri: source,\n overridingExtension: null,\n },\n fullInitialStatus,\n };\n }\n\n // Download first if necessary.\n const asset = _getAssetFromPlaybackSource(source);\n if (downloadFirst && asset) {\n // TODO we can download remote uri too once @nikki93 has integrated this into Asset\n await asset.downloadAsync();\n }\n\n // Get the native source\n const nativeSource: AVPlaybackNativeSource | null = getNativeSourceFromSource(source);\n\n if (nativeSource === null) {\n throw new Error(`Cannot load an AV asset from a null playback source`);\n }\n\n return { nativeSource, fullInitialStatus };\n}\n\nexport function getUnloadedStatus(error: string | null = null): AVPlaybackStatus {\n return {\n isLoaded: false,\n ...(error ? { error } : null),\n };\n}\n\nexport interface AV {\n setStatusAsync(status: AVPlaybackStatusToSet): Promise;\n getStatusAsync(): Promise;\n}\n\nexport interface Playback extends AV {\n playAsync(): Promise;\n loadAsync(source: AVPlaybackSource, initialStatus: AVPlaybackStatusToSet, downloadAsync: boolean);\n unloadAsync(): Promise;\n playFromPositionAsync(\n positionMillis: number,\n tolerances?: { toleranceMillisBefore?: number; toleranceMillisAfter?: number }\n ): Promise;\n pauseAsync(): Promise;\n stopAsync(): Promise;\n replayAsync(status: AVPlaybackStatusToSet): Promise;\n setPositionAsync(\n positionMillis: number,\n tolerances?: { toleranceMillisBefore?: number; toleranceMillisAfter?: number }\n ): Promise;\n setRateAsync(\n rate: number,\n shouldCorrectPitch: boolean,\n pitchCorrectionQuality?: PitchCorrectionQuality\n ): Promise;\n setVolumeAsync(volume: number): Promise;\n setIsMutedAsync(isMuted: boolean): Promise;\n setIsLoopingAsync(isLooping: boolean): Promise;\n setProgressUpdateIntervalAsync(progressUpdateIntervalMillis: number): Promise;\n}\n\n/**\n * A mixin that defines common playback methods for A/V classes so they implement the `Playback`\n * interface\n */\nexport const PlaybackMixin = {\n async playAsync(): Promise {\n return ((this as any) as Playback).setStatusAsync({ shouldPlay: true });\n },\n\n async playFromPositionAsync(\n positionMillis: number,\n tolerances: { toleranceMillisBefore?: number; toleranceMillisAfter?: number } = {}\n ): Promise {\n return ((this as any) as Playback).setStatusAsync({\n positionMillis,\n shouldPlay: true,\n seekMillisToleranceAfter: tolerances.toleranceMillisAfter,\n seekMillisToleranceBefore: tolerances.toleranceMillisBefore,\n });\n },\n\n async pauseAsync(): Promise {\n return ((this as any) as Playback).setStatusAsync({ shouldPlay: false });\n },\n\n async stopAsync(): Promise {\n return ((this as any) as Playback).setStatusAsync({ positionMillis: 0, shouldPlay: false });\n },\n\n async setPositionAsync(\n positionMillis: number,\n tolerances: { toleranceMillisBefore?: number; toleranceMillisAfter?: number } = {}\n ): Promise {\n return ((this as any) as Playback).setStatusAsync({\n positionMillis,\n seekMillisToleranceAfter: tolerances.toleranceMillisAfter,\n seekMillisToleranceBefore: tolerances.toleranceMillisBefore,\n });\n },\n\n async setRateAsync(\n rate: number,\n shouldCorrectPitch: boolean = false,\n pitchCorrectionQuality: PitchCorrectionQuality = PitchCorrectionQuality.Low\n ): Promise {\n return ((this as any) as Playback).setStatusAsync({\n rate,\n shouldCorrectPitch,\n pitchCorrectionQuality,\n });\n },\n\n async setVolumeAsync(volume: number): Promise {\n return ((this as any) as Playback).setStatusAsync({ volume });\n },\n\n async setIsMutedAsync(isMuted: boolean): Promise {\n return ((this as any) as Playback).setStatusAsync({ isMuted });\n },\n\n async setIsLoopingAsync(isLooping: boolean): Promise {\n return ((this as any) as Playback).setStatusAsync({ isLooping });\n },\n\n async setProgressUpdateIntervalAsync(\n progressUpdateIntervalMillis: number\n ): Promise {\n return ((this as any) as Playback).setStatusAsync({ progressUpdateIntervalMillis });\n },\n};\n"]} \ No newline at end of file +{"version":3,"file":"AV.js","sourceRoot":"","sources":["../src/AV.ts"],"names":[],"mappings":"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","sourcesContent":["import { Platform } from '@unimodules/core';\nimport { Asset } from 'expo-asset';\n\nimport ExponentAV from './ExponentAV';\n// TODO add:\n// disableFocusOnAndroid\n// audio routes (at least did become noisy on android)\n// pan\n// pitch\n// API to explicitly request audio focus / session\n// API to select stream type on Android\n// subtitles API\n\nexport enum PitchCorrectionQuality {\n Low = ExponentAV && ExponentAV.Qualities && ExponentAV.Qualities.Low,\n Medium = ExponentAV && ExponentAV.Qualities && ExponentAV.Qualities.Medium,\n High = ExponentAV && ExponentAV.Qualities && ExponentAV.Qualities.High,\n}\n\nexport type AVPlaybackSource =\n | number\n | {\n uri: string;\n overrideFileExtensionAndroid?: string;\n headers?: { [fieldName: string]: string };\n }\n | Asset;\n\nexport type AVPlaybackNativeSource = {\n uri: string;\n overridingExtension?: string | null;\n headers?: { [fieldName: string]: string };\n};\n\nexport type AVPlaybackStatus =\n | {\n isLoaded: false;\n androidImplementation?: string;\n error?: string; // populated exactly once when an error forces the object to unload\n }\n | {\n isLoaded: true;\n androidImplementation?: string;\n\n uri: string;\n\n progressUpdateIntervalMillis: number;\n durationMillis?: number;\n positionMillis: number;\n playableDurationMillis?: number;\n seekMillisToleranceBefore?: number;\n seekMillisToleranceAfter?: number;\n\n shouldPlay: boolean;\n isPlaying: boolean;\n isBuffering: boolean;\n\n rate: number;\n shouldCorrectPitch: boolean;\n volume: number;\n isMuted: boolean;\n isLooping: boolean;\n\n didJustFinish: boolean; // true exactly once when the track plays to finish\n };\n\nexport type AVPlaybackStatusToSet = {\n androidImplementation?: string;\n progressUpdateIntervalMillis?: number;\n positionMillis?: number;\n seekMillisToleranceBefore?: number;\n seekMillisToleranceAfter?: number;\n shouldPlay?: boolean;\n rate?: number;\n shouldCorrectPitch?: boolean;\n volume?: number;\n isMuted?: boolean;\n isLooping?: boolean;\n pitchCorrectionQuality?: PitchCorrectionQuality;\n};\n\nexport const _DEFAULT_PROGRESS_UPDATE_INTERVAL_MILLIS: number = 500;\nexport const _DEFAULT_INITIAL_PLAYBACK_STATUS: AVPlaybackStatusToSet = {\n positionMillis: 0,\n progressUpdateIntervalMillis: _DEFAULT_PROGRESS_UPDATE_INTERVAL_MILLIS,\n shouldPlay: false,\n rate: 1.0,\n shouldCorrectPitch: false,\n volume: 1.0,\n isMuted: false,\n isLooping: false,\n};\n\nexport function getNativeSourceFromSource(\n source?: AVPlaybackSource | null\n): AVPlaybackNativeSource | null {\n let uri: string | null = null;\n let overridingExtension: string | null = null;\n let headers: { [fieldName: string]: string } | undefined;\n\n if (typeof source === 'string' && Platform.OS === 'web') {\n return {\n uri: source,\n overridingExtension,\n headers,\n };\n }\n\n const asset: Asset | null = _getAssetFromPlaybackSource(source);\n if (asset != null) {\n uri = asset.localUri || asset.uri;\n } else if (\n source != null &&\n typeof source !== 'number' &&\n 'uri' in source &&\n typeof source.uri === 'string'\n ) {\n uri = source.uri;\n }\n\n if (uri == null) {\n return null;\n }\n\n if (\n source != null &&\n typeof source !== 'number' &&\n 'overrideFileExtensionAndroid' in source &&\n typeof source.overrideFileExtensionAndroid === 'string'\n ) {\n overridingExtension = source.overrideFileExtensionAndroid;\n }\n\n if (\n source != null &&\n typeof source !== 'number' &&\n 'headers' in source &&\n typeof source.headers === 'object'\n ) {\n headers = source.headers;\n }\n return { uri, overridingExtension, headers };\n}\n\nfunction _getAssetFromPlaybackSource(source?: AVPlaybackSource | null): Asset | null {\n if (source == null) {\n return null;\n }\n\n let asset: Asset | null = null;\n if (typeof source === 'number') {\n asset = Asset.fromModule(source);\n } else if (source instanceof Asset) {\n asset = source;\n }\n return asset;\n}\n\nexport function assertStatusValuesInBounds(status: AVPlaybackStatusToSet): void {\n if (typeof status.rate === 'number' && (status.rate < 0 || status.rate > 32)) {\n throw new RangeError('Rate value must be between 0.0 and 32.0');\n }\n if (typeof status.volume === 'number' && (status.volume < 0 || status.volume > 1)) {\n throw new RangeError('Volume value must be between 0.0 and 1.0');\n }\n}\n\nexport async function getNativeSourceAndFullInitialStatusForLoadAsync(\n source: AVPlaybackSource | null,\n initialStatus: AVPlaybackStatusToSet | null,\n downloadFirst: boolean\n): Promise<{\n nativeSource: AVPlaybackNativeSource;\n fullInitialStatus: AVPlaybackStatusToSet;\n}> {\n // Get the full initial status\n const fullInitialStatus: AVPlaybackStatusToSet =\n initialStatus == null\n ? _DEFAULT_INITIAL_PLAYBACK_STATUS\n : {\n ..._DEFAULT_INITIAL_PLAYBACK_STATUS,\n ...initialStatus,\n };\n assertStatusValuesInBounds(fullInitialStatus);\n\n if (typeof source === 'string' && Platform.OS === 'web') {\n return {\n nativeSource: {\n uri: source,\n overridingExtension: null,\n },\n fullInitialStatus,\n };\n }\n\n // Download first if necessary.\n const asset = _getAssetFromPlaybackSource(source);\n if (downloadFirst && asset) {\n // TODO we can download remote uri too once @nikki93 has integrated this into Asset\n await asset.downloadAsync();\n }\n\n // Get the native source\n const nativeSource: AVPlaybackNativeSource | null = getNativeSourceFromSource(source);\n\n if (nativeSource === null) {\n throw new Error(`Cannot load an AV asset from a null playback source`);\n }\n\n return { nativeSource, fullInitialStatus };\n}\n\nexport function getUnloadedStatus(error: string | null = null): AVPlaybackStatus {\n return {\n isLoaded: false,\n ...(error ? { error } : null),\n };\n}\n\nexport interface AV {\n setStatusAsync(status: AVPlaybackStatusToSet): Promise;\n getStatusAsync(): Promise;\n}\n\nexport interface Playback extends AV {\n playAsync(): Promise;\n loadAsync(\n source: AVPlaybackSource,\n initialStatus: AVPlaybackStatusToSet,\n downloadAsync: boolean\n ): Promise;\n unloadAsync(): Promise;\n playFromPositionAsync(\n positionMillis: number,\n tolerances?: { toleranceMillisBefore?: number; toleranceMillisAfter?: number }\n ): Promise;\n pauseAsync(): Promise;\n stopAsync(): Promise;\n replayAsync(status: AVPlaybackStatusToSet): Promise;\n setPositionAsync(\n positionMillis: number,\n tolerances?: { toleranceMillisBefore?: number; toleranceMillisAfter?: number }\n ): Promise;\n setRateAsync(\n rate: number,\n shouldCorrectPitch: boolean,\n pitchCorrectionQuality?: PitchCorrectionQuality\n ): Promise;\n setVolumeAsync(volume: number): Promise;\n setIsMutedAsync(isMuted: boolean): Promise;\n setIsLoopingAsync(isLooping: boolean): Promise;\n setProgressUpdateIntervalAsync(progressUpdateIntervalMillis: number): Promise;\n}\n\n/**\n * A mixin that defines common playback methods for A/V classes so they implement the `Playback`\n * interface\n */\nexport const PlaybackMixin = {\n async playAsync(): Promise {\n return ((this as any) as Playback).setStatusAsync({ shouldPlay: true });\n },\n\n async playFromPositionAsync(\n positionMillis: number,\n tolerances: { toleranceMillisBefore?: number; toleranceMillisAfter?: number } = {}\n ): Promise {\n return ((this as any) as Playback).setStatusAsync({\n positionMillis,\n shouldPlay: true,\n seekMillisToleranceAfter: tolerances.toleranceMillisAfter,\n seekMillisToleranceBefore: tolerances.toleranceMillisBefore,\n });\n },\n\n async pauseAsync(): Promise {\n return ((this as any) as Playback).setStatusAsync({ shouldPlay: false });\n },\n\n async stopAsync(): Promise {\n return ((this as any) as Playback).setStatusAsync({ positionMillis: 0, shouldPlay: false });\n },\n\n async setPositionAsync(\n positionMillis: number,\n tolerances: { toleranceMillisBefore?: number; toleranceMillisAfter?: number } = {}\n ): Promise {\n return ((this as any) as Playback).setStatusAsync({\n positionMillis,\n seekMillisToleranceAfter: tolerances.toleranceMillisAfter,\n seekMillisToleranceBefore: tolerances.toleranceMillisBefore,\n });\n },\n\n async setRateAsync(\n rate: number,\n shouldCorrectPitch: boolean = false,\n pitchCorrectionQuality: PitchCorrectionQuality = PitchCorrectionQuality.Low\n ): Promise {\n return ((this as any) as Playback).setStatusAsync({\n rate,\n shouldCorrectPitch,\n pitchCorrectionQuality,\n });\n },\n\n async setVolumeAsync(volume: number): Promise {\n return ((this as any) as Playback).setStatusAsync({ volume });\n },\n\n async setIsMutedAsync(isMuted: boolean): Promise {\n return ((this as any) as Playback).setStatusAsync({ isMuted });\n },\n\n async setIsLoopingAsync(isLooping: boolean): Promise {\n return ((this as any) as Playback).setStatusAsync({ isLooping });\n },\n\n async setProgressUpdateIntervalAsync(\n progressUpdateIntervalMillis: number\n ): Promise {\n return ((this as any) as Playback).setStatusAsync({ progressUpdateIntervalMillis });\n },\n};\n"]} \ No newline at end of file diff --git a/src/AV.ts b/src/AV.ts index 9e74a7991452f..69659f084308e 100644 --- a/src/AV.ts +++ b/src/AV.ts @@ -224,7 +224,11 @@ export interface AV { export interface Playback extends AV { playAsync(): Promise; - loadAsync(source: AVPlaybackSource, initialStatus: AVPlaybackStatusToSet, downloadAsync: boolean); + loadAsync( + source: AVPlaybackSource, + initialStatus: AVPlaybackStatusToSet, + downloadAsync: boolean + ): Promise; unloadAsync(): Promise; playFromPositionAsync( positionMillis: number,