expo-video-subtitle 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +184 -120
- package/FORK.md +32 -17
- package/LICENSE +21 -21
- package/README.md +209 -186
- package/android/build.gradle +32 -32
- package/android/src/main/AndroidManifest.xml +10 -10
- package/android/src/main/java/expo/modules/video/FullscreenPlayerActivity.kt +270 -258
- package/android/src/main/java/expo/modules/video/IntervalUpdateClock.kt +54 -54
- package/android/src/main/java/expo/modules/video/MediaMetadataRetriever.kt +89 -89
- package/android/src/main/java/expo/modules/video/PlayerViewExtension.kt +87 -87
- package/android/src/main/java/expo/modules/video/VideoCache.kt +109 -109
- package/android/src/main/java/expo/modules/video/VideoExceptions.kt +45 -45
- package/android/src/main/java/expo/modules/video/VideoModule.kt +446 -446
- package/android/src/main/java/expo/modules/video/VideoThumbnail.kt +20 -20
- package/android/src/main/java/expo/modules/video/VideoView.kt +461 -457
- package/android/src/main/java/expo/modules/video/delegates/IgnoreSameSet.kt +24 -24
- package/android/src/main/java/expo/modules/video/drawing/OutlineProvider.kt +217 -217
- package/android/src/main/java/expo/modules/video/enums/AudioMixingMode.kt +20 -20
- package/android/src/main/java/expo/modules/video/enums/ContentFit.kt +19 -19
- package/android/src/main/java/expo/modules/video/enums/ContentType.kt +22 -22
- package/android/src/main/java/expo/modules/video/enums/DRMType.kt +26 -26
- package/android/src/main/java/expo/modules/video/enums/FullscreenOrientation.kt +25 -25
- package/android/src/main/java/expo/modules/video/enums/PlayerStatus.kt +10 -10
- package/android/src/main/java/expo/modules/video/enums/VideoRange.kt +27 -27
- package/android/src/main/java/expo/modules/video/listeners/VideoManagerListener.kt +10 -10
- package/android/src/main/java/expo/modules/video/listeners/VideoPlayerListener.kt +35 -35
- package/android/src/main/java/expo/modules/video/listeners/VideoViewListener.kt +13 -13
- package/android/src/main/java/expo/modules/video/managers/AudioFocusManager.kt +242 -242
- package/android/src/main/java/expo/modules/video/managers/PictureInPictureManager.kt +329 -329
- package/android/src/main/java/expo/modules/video/managers/VideoManager.kt +194 -194
- package/android/src/main/java/expo/modules/video/playbackService/ExpoVideoPlaybackService.kt +267 -267
- package/android/src/main/java/expo/modules/video/playbackService/PlaybackServiceConnection.kt +62 -62
- package/android/src/main/java/expo/modules/video/playbackService/VideoMediaSessionCallback.kt +47 -47
- package/android/src/main/java/expo/modules/video/player/DefaultLoadControl.java +551 -551
- package/android/src/main/java/expo/modules/video/player/FirstFrameEventGenerator.kt +116 -116
- package/android/src/main/java/expo/modules/video/player/PlayerEvent.kt +172 -172
- package/android/src/main/java/expo/modules/video/player/VideoPlayer.kt +609 -598
- package/android/src/main/java/expo/modules/video/player/VideoPlayerAudioTracks.kt +126 -126
- package/android/src/main/java/expo/modules/video/player/VideoPlayerKeepAwake.kt +91 -91
- package/android/src/main/java/expo/modules/video/player/VideoPlayerLoadControl.kt +57 -57
- package/android/src/main/java/expo/modules/video/player/VideoPlayerSubtitles.kt +136 -136
- package/android/src/main/java/expo/modules/video/records/BufferOptions.kt +18 -18
- package/android/src/main/java/expo/modules/video/records/ButtonOptions.kt +17 -17
- package/android/src/main/java/expo/modules/video/records/DRMOptions.kt +27 -27
- package/android/src/main/java/expo/modules/video/records/FullscreenOptions.kt +14 -14
- package/android/src/main/java/expo/modules/video/records/PiPParams.kt +38 -38
- package/android/src/main/java/expo/modules/video/records/PlaybackError.kt +21 -21
- package/android/src/main/java/expo/modules/video/records/PlayerBuilderOptions.kt +15 -15
- package/android/src/main/java/expo/modules/video/records/ScrubbingModeOptions.kt +33 -33
- package/android/src/main/java/expo/modules/video/records/SeekTolerance.kt +30 -30
- package/android/src/main/java/expo/modules/video/records/SubtitleSource.kt +54 -54
- package/android/src/main/java/expo/modules/video/records/SubtitleStyle.kt +144 -137
- package/android/src/main/java/expo/modules/video/records/Tracks.kt +115 -115
- package/android/src/main/java/expo/modules/video/records/VideoEventPayloads.kt +79 -79
- package/android/src/main/java/expo/modules/video/records/VideoMetadata.kt +14 -14
- package/android/src/main/java/expo/modules/video/records/VideoSize.kt +16 -16
- package/android/src/main/java/expo/modules/video/records/VideoSource.kt +113 -113
- package/android/src/main/java/expo/modules/video/records/VideoThumbnailOptions.kt +26 -26
- package/android/src/main/java/expo/modules/video/utils/DataSourceUtils.kt +81 -81
- package/android/src/main/java/expo/modules/video/utils/EventDispatcherUtils.kt +43 -43
- package/android/src/main/java/expo/modules/video/utils/FullscreenActivityOrientationHelper.kt +120 -120
- package/android/src/main/java/expo/modules/video/utils/MediaSessionUtils.kt +14 -14
- package/android/src/main/java/expo/modules/video/utils/MutableWeakReference.kt +26 -26
- package/android/src/main/java/expo/modules/video/utils/PictureInPictureHelperFragment.kt +49 -49
- package/android/src/main/java/expo/modules/video/utils/PictureInPictureUtils.kt +96 -96
- package/android/src/main/java/expo/modules/video/utils/RoundedSubtitleBackground.kt +352 -0
- package/android/src/main/java/expo/modules/video/utils/StackingSubtitleParser.kt +4 -1
- package/android/src/main/java/expo/modules/video/utils/SubtitleUtils.kt +131 -78
- package/android/src/main/java/expo/modules/video/utils/ViewVisibilityUtils.kt +28 -28
- package/android/src/main/java/expo/modules/video/utils/WeakMutableSet.kt +120 -120
- package/android/src/main/java/expo/modules/video/utils/YogaUtils.kt +20 -20
- package/android/src/main/res/drawable/seek_backwards_10s.xml +25 -25
- package/android/src/main/res/drawable/seek_backwards_15s.xml +25 -25
- package/android/src/main/res/drawable/seek_backwards_5s.xml +25 -25
- package/android/src/main/res/drawable/seek_forwards_10s.xml +30 -30
- package/android/src/main/res/drawable/seek_forwards_15s.xml +31 -31
- package/android/src/main/res/drawable/seek_forwards_5s.xml +30 -30
- package/android/src/main/res/layout/fullscreen_player_activity.xml +20 -20
- package/android/src/main/res/layout/surface_player_view.xml +7 -7
- package/android/src/main/res/layout/texture_player_view.xml +7 -7
- package/android/src/main/res/values/styles.xml +9 -9
- package/app.plugin.js +1 -1
- package/build/NativeVideoAirPlayButtonView.js.map +1 -1
- package/build/NativeVideoModule.js.map +1 -1
- package/build/NativeVideoModule.web.js.map +1 -1
- package/build/NativeVideoView.js.map +1 -1
- package/build/VideoAirPlayButton.ios.js.map +1 -1
- package/build/VideoAirPlayButton.js.map +1 -1
- package/build/VideoAirPlayButton.types.js.map +1 -1
- package/build/VideoModule.js.map +1 -1
- package/build/VideoPlayer.js.map +1 -1
- package/build/VideoPlayer.types.js.map +1 -1
- package/build/VideoPlayer.web.js.map +1 -1
- package/build/VideoPlayerEvents.types.js.map +1 -1
- package/build/VideoThumbnail.js.map +1 -1
- package/build/VideoView.js.map +1 -1
- package/build/VideoView.types.d.ts +14 -0
- package/build/VideoView.types.d.ts.map +1 -1
- package/build/VideoView.types.js.map +1 -1
- package/build/VideoView.web.js.map +1 -1
- package/build/index.js.map +1 -1
- package/build/resolveAssetSource.js.map +1 -1
- package/build/resolveAssetSource.web.js.map +1 -1
- package/expo-module.config.json +9 -9
- package/ios/Cache/CachableRequest.swift +46 -46
- package/ios/Cache/CacheVideoAssetTransportProvider.swift +64 -64
- package/ios/Cache/CachedResource.swift +164 -164
- package/ios/Cache/CachingHelpers.swift +107 -107
- package/ios/Cache/MediaFileHandle.swift +139 -139
- package/ios/Cache/MediaInfo.swift +185 -185
- package/ios/Cache/ResourceLoaderDelegate.swift +306 -306
- package/ios/Cache/SynchronizedHashTable.swift +23 -23
- package/ios/Cache/VideoCacheManager.swift +192 -192
- package/ios/ContentKeyDelegate.swift +214 -214
- package/ios/ContentKeyManager.swift +21 -21
- package/ios/Enums/AudioMixingMode.swift +37 -37
- package/ios/Enums/ContentType.swift +11 -11
- package/ios/Enums/DRMType.swift +20 -20
- package/ios/Enums/FullscreenOrientation.swift +34 -34
- package/ios/Enums/KeepFullscreenOnPiPStopBehavior.swift +20 -20
- package/ios/Enums/PlayerStatus.swift +10 -10
- package/ios/Enums/VideoContentFit.swift +39 -39
- package/ios/Enums/VideoRange.swift +21 -21
- package/ios/ExpoVideo.podspec +27 -27
- package/ios/NowPlayingManager.swift +304 -304
- package/ios/OrientationAVPlayerViewController.swift +263 -263
- package/ios/Records/BufferOptions.swift +12 -12
- package/ios/Records/DRMOptions.swift +24 -24
- package/ios/Records/FullscreenOptions.swift +14 -14
- package/ios/Records/PlaybackError.swift +10 -10
- package/ios/Records/ScrubbingModeOptions.swift +7 -7
- package/ios/Records/SeekTolerance.swift +20 -20
- package/ios/Records/SubtitleSource.swift +32 -32
- package/ios/Records/SubtitleStyle.swift +118 -118
- package/ios/Records/Tracks.swift +229 -229
- package/ios/Records/VideoEventPayloads.swift +81 -81
- package/ios/Records/VideoMetadata.swift +16 -16
- package/ios/Records/VideoSize.swift +15 -15
- package/ios/Records/VideoSource.swift +28 -28
- package/ios/Thumbnails/VideoThumbnail.swift +27 -27
- package/ios/Thumbnails/VideoThumbnailGenerator.swift +68 -68
- package/ios/Thumbnails/VideoThumbnailOptions.swift +15 -15
- package/ios/Utils/AVAssetVariant+VideoTracks.swift +20 -20
- package/ios/Utils/AvAssetTrack+VideoTracks.swift +79 -79
- package/ios/Utils/FourCharCode+toString.swift +25 -25
- package/ios/Utils/HlsUriUtils.swift +27 -27
- package/ios/Utils/URL+MediaLibraryAssets.swift +68 -68
- package/ios/VideoAirPlayButtonView.swift +70 -70
- package/ios/VideoAsset.swift +98 -98
- package/ios/VideoAssetTransport/VideoAssetLoadPlan.swift +69 -69
- package/ios/VideoAssetTransport/VideoAssetSourceDescriptor.swift +29 -29
- package/ios/VideoAssetTransport/VideoAssetTransportProvider.swift +24 -24
- package/ios/VideoAssetTransport/VideoAssetTransportRegistry.swift +103 -103
- package/ios/VideoExceptions.swift +53 -53
- package/ios/VideoItem.swift +11 -11
- package/ios/VideoManager.swift +182 -182
- package/ios/VideoModule.swift +413 -413
- package/ios/VideoPlayer/DangerousPropertiesStore.swift +19 -19
- package/ios/VideoPlayer.swift +485 -485
- package/ios/VideoPlayerAudioTracks.swift +109 -109
- package/ios/VideoPlayerItem.swift +169 -169
- package/ios/VideoPlayerObserver.swift +612 -612
- package/ios/VideoPlayerSeeker.swift +77 -77
- package/ios/VideoPlayerSubtitleSideload.swift +203 -203
- package/ios/VideoPlayerSubtitles.swift +88 -88
- package/ios/VideoSourceLoader.swift +90 -90
- package/ios/VideoSourceLoaderListener.swift +34 -34
- package/ios/VideoView.swift +201 -201
- package/package.json +51 -51
- package/plugin/index.d.ts +1 -1
- package/plugin/index.js +1 -1
- package/plugin/jest.config.js +1 -1
- package/plugin/src/index.ts +3 -3
- package/plugin/src/withExpoVideo.ts +103 -103
- package/plugin/tsconfig.json +10 -10
- package/src/NativeVideoAirPlayButtonView.ts +3 -3
- package/src/NativeVideoModule.ts +16 -16
- package/src/NativeVideoModule.web.ts +4 -4
- package/src/NativeVideoView.ts +8 -8
- package/src/VideoAirPlayButton.ios.tsx +8 -8
- package/src/VideoAirPlayButton.tsx +14 -14
- package/src/VideoAirPlayButton.types.ts +39 -39
- package/src/VideoModule.ts +47 -47
- package/src/VideoPlayer.tsx +74 -74
- package/src/VideoPlayer.types.ts +893 -893
- package/src/VideoPlayer.web.tsx +470 -470
- package/src/VideoPlayerEvents.types.ts +332 -332
- package/src/VideoThumbnail.ts +31 -31
- package/src/VideoView.tsx +111 -111
- package/src/VideoView.types.ts +454 -439
- package/src/VideoView.web.tsx +293 -293
- package/src/index.ts +26 -26
- package/src/resolveAssetSource.ts +2 -2
- package/src/resolveAssetSource.web.ts +17 -17
- package/src/ts-declarations/react-native-assets.d.ts +22 -22
- package/tsconfig.json +10 -10
- package/.gitattributes +0 -17
- package/eslint.config.js +0 -4
- package/plugin/tsconfig.tsbuildinfo +0 -1
- package/tsconfig.all.json +0 -11
- package/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,120 +1,184 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this package are documented here.
|
|
4
|
-
|
|
5
|
-
This package is a fork of [`expo-video`](https://github.com/expo/expo/tree/main/packages/expo-video).
|
|
6
|
-
Changes inherited from the upstream base version are not repeated here — see the
|
|
7
|
-
[upstream changelog](https://github.com/expo/expo/blob/main/packages/expo-video/CHANGELOG.md)
|
|
8
|
-
for the history of everything that isn't subtitle related.
|
|
9
|
-
|
|
10
|
-
## 0.
|
|
11
|
-
|
|
12
|
-
### Added
|
|
13
|
-
|
|
14
|
-
- **Android:** `subtitleStyle.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
###
|
|
118
|
-
|
|
119
|
-
-
|
|
120
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this package are documented here.
|
|
4
|
+
|
|
5
|
+
This package is a fork of [`expo-video`](https://github.com/expo/expo/tree/main/packages/expo-video).
|
|
6
|
+
Changes inherited from the upstream base version are not repeated here — see the
|
|
7
|
+
[upstream changelog](https://github.com/expo/expo/blob/main/packages/expo-video/CHANGELOG.md)
|
|
8
|
+
for the history of everything that isn't subtitle related.
|
|
9
|
+
|
|
10
|
+
## 0.3.0
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Android:** `subtitleStyle.backgroundRadius` rounds the corners of the `backgroundColor` box, in dp.
|
|
15
|
+
One box is drawn per rendered line, so a caption that wraps gets two rounded boxes stacked on each
|
|
16
|
+
other, the way VLC and most desktop players draw them. It has no effect unless `backgroundColor` is
|
|
17
|
+
set to something that is not fully transparent, and `windowColor` is deliberately left rectangular —
|
|
18
|
+
the window is the region the caption occupies, the background is the box that hugs the text.
|
|
19
|
+
|
|
20
|
+
Media3 offers nothing for this. `SubtitlePainter` renders `backgroundColor` as an Android
|
|
21
|
+
`BackgroundColorSpan`, which the framework paints with `canvas.drawRect`, and it paints `windowColor`
|
|
22
|
+
with a `canvas.drawRect` of its own; neither takes a radius, and `SubtitlePainter` and
|
|
23
|
+
`CanvasSubtitleOutput` are package-private and final while `SubtitleView` is final, so none of it can
|
|
24
|
+
be subclassed or replaced. The background is therefore drawn by a second subtitle view inserted
|
|
25
|
+
behind the one `PlayerView` owns, fed the same cues and configured with the same typeface, text size
|
|
26
|
+
and bottom padding so the two layouts match; the box itself comes from a `LineBackgroundSpan` calling
|
|
27
|
+
`drawRoundRect`. That view pins its edge type to `EDGE_TYPE_NONE` on purpose: `SubtitlePainter` copies
|
|
28
|
+
the cue text for a second edge pass and draws both layouts whenever the edge type is `outline`,
|
|
29
|
+
`raised` or `depressed`, which would paint the box twice and make a semi-transparent colour composite
|
|
30
|
+
with itself and come out darker than asked for.
|
|
31
|
+
|
|
32
|
+
Leaving `backgroundRadius` unset takes the original code path unchanged, with no extra view and no
|
|
33
|
+
extra listener.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- **Android:** the subtitle view is now reconfigured whenever a player moves between views —
|
|
38
|
+
attaching a player, entering fullscreen, leaving it. `PlayerView` re-attaches its own subtitle view
|
|
39
|
+
on `setPlayer`, so nothing needed this before; the rounded background does, because it subscribes to
|
|
40
|
+
the `Player` rather than riding on `PlayerView`, and a view that no longer drives the player would
|
|
41
|
+
otherwise keep that subscription and go on drawing cues behind a surface nobody is looking at. For
|
|
42
|
+
anyone not using `backgroundRadius` this only means the caption style is re-applied at those
|
|
43
|
+
moments, which is what it already was.
|
|
44
|
+
|
|
45
|
+
## 0.2.2
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- The published tarball no longer carries the repo's own development configuration: `.prettierrc`,
|
|
50
|
+
`.gitattributes`, `eslint.config.js`, `tsconfig.all.json` and the two `*.tsbuildinfo` build caches
|
|
51
|
+
(260 files → 254). None of it is read from inside a consumer's `node_modules`, and
|
|
52
|
+
`eslint.config.js` would in fact throw if anything did load it, because it requires
|
|
53
|
+
`expo-module-scripts` — a devDependency, and therefore absent for consumers. Two conventions
|
|
54
|
+
combined to publish these: `.npmignore` excludes hidden *directories* but not hidden *files*, and
|
|
55
|
+
npm ignores `.gitignore` entirely once an `.npmignore` exists, so a build cache that git already
|
|
56
|
+
ignores still shipped. Nothing a consumer uses changed — the file list is otherwise byte-identical,
|
|
57
|
+
and installing the tarball into a clean project still resolves `build/`, `plugin/build/`,
|
|
58
|
+
`app.plugin.js`, `expo-module.config.json` and the Android/iOS sources.
|
|
59
|
+
- Dropped the `.npmignore` entry for `oxlint.config.mjs`, which has not existed since 0.2.0.
|
|
60
|
+
|
|
61
|
+
## 0.2.1
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
|
|
65
|
+
- Repository tooling, with no effect on the published runtime: `npm run lint` is quiet again. Making
|
|
66
|
+
the lint step runnable in 0.2.0 exposed 377 `prettier/prettier` warnings against code that is in
|
|
67
|
+
fact correctly formatted. `eslint-config-universe` enables the `prettier/prettier` rule but supplies
|
|
68
|
+
no options of its own, and `expo-video` inherits them from the Expo monorepo's root `.prettierrc` —
|
|
69
|
+
a file that does not come along when the package is forked out to stand on its own. Prettier
|
|
70
|
+
therefore fell back to its own defaults, and every source file disagreed with them about quote style
|
|
71
|
+
and line width. Adding the upstream options as a `.prettierrc` takes the count to zero without
|
|
72
|
+
reformatting a single line.
|
|
73
|
+
|
|
74
|
+
## 0.2.0
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
|
|
78
|
+
- **Android:** `subtitleStyle.applyEmbeddedStyles` keeps the inline formatting a subtitle track
|
|
79
|
+
carries instead of discarding it. Subtitle formats bring styling of their own — SubRip's `<b>`,
|
|
80
|
+
`<i>`, `<u>` and `<font color>` tags, and the richer per-cue styling of embedded WebVTT/TTML — and
|
|
81
|
+
until now every bit of it was thrown away so that `subtitleStyle` was the only thing deciding how
|
|
82
|
+
captions looked. `SubtitleView.setApplyEmbeddedStyles(false)` was hardcoded, and Media3 implements
|
|
83
|
+
that by removing every span from every cue, so an `.srt` written with `<i>` rendered upright.
|
|
84
|
+
Defaults to `false`, so nothing changes until you opt in. The rest of `subtitleStyle` still applies
|
|
85
|
+
underneath and `fontSize` still overrides any size the track asks for; the trade-off is that a cue
|
|
86
|
+
specifying its own colours overrides `textColor` and `windowColor` for that cue. There is no iOS
|
|
87
|
+
equivalent: `AVPlayerItem.textStyleRules` always composes with what the WebVTT cue declares.
|
|
88
|
+
|
|
89
|
+
### Fixed
|
|
90
|
+
|
|
91
|
+
- **Android:** a subtitle no longer drops down a line when the subtitle *below* it ends. Cues that
|
|
92
|
+
are on screen together are drawn as one block anchored at its bottom, so the moment the lower cue
|
|
93
|
+
expired the upper one fell into its place — moving the text at exactly the spot the viewer is
|
|
94
|
+
reading. Every cue now keeps the same line for its whole time on screen: the line a finished cue
|
|
95
|
+
leaves behind is held empty, and the next cue to start reclaims the lowest empty line rather than
|
|
96
|
+
stacking on top, which is what keeps the block from creeping upwards. An empty line can therefore
|
|
97
|
+
sit below — or between — the cues still on screen, and the stack resets once nothing is left on
|
|
98
|
+
screen. Cues with explicit `{\anN}` positioning are still passed through untouched.
|
|
99
|
+
- **Android:** merging simultaneous SubRip cues no longer flattens their text. The cues were joined
|
|
100
|
+
through `toString()`, which erases the spans Media3's SubRip parser produces from inline tags. This
|
|
101
|
+
changed nothing on screen at the time, because the renderer stripped those spans anyway, but it
|
|
102
|
+
would have silently defeated the new `applyEmbeddedStyles` option for any overlapping cue.
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
|
|
106
|
+
- Repository tooling, with no effect on the published runtime: `npm run lint` runs again. The repo
|
|
107
|
+
had no `eslint.config.js` — `expo-module configure` treats it as an optional template and never
|
|
108
|
+
creates one — while the `oxlint.config.mjs` it did have re-exported a module that
|
|
109
|
+
`expo-module-scripts@56` does not ship, so the lint step in `FORK.md` §5 had never actually
|
|
110
|
+
executed. A `.gitattributes` now pins the working copy to LF, which stops the Prettier rule from
|
|
111
|
+
reporting nearly every line of every file on a Windows checkout. The single lint error this
|
|
112
|
+
uncovered, a non-simple expression in a `useMemo` dependency list in `VideoPlayer.web.tsx`, is
|
|
113
|
+
fixed by hoisting it into a variable; the value and its identity semantics are unchanged.
|
|
114
|
+
|
|
115
|
+
## 0.1.3
|
|
116
|
+
|
|
117
|
+
### Documentation
|
|
118
|
+
|
|
119
|
+
- Document how subtitles that are on screen at the same time are stacked, which shipped in 0.1.2 but
|
|
120
|
+
was only described in the changelog.
|
|
121
|
+
- Add a release procedure to `FORK.md`, including the rule that every version bump carries a
|
|
122
|
+
changelog entry.
|
|
123
|
+
|
|
124
|
+
## 0.1.2
|
|
125
|
+
|
|
126
|
+
### Fixed
|
|
127
|
+
|
|
128
|
+
- **Android:** subtitles that are on screen at the same time are now stacked as one block instead of
|
|
129
|
+
being drawn on top of each other. `.srt` files legitimately contain overlapping timestamps (two
|
|
130
|
+
speakers, dialogue over on-screen text), but SubRip carries no positioning, so Media3 pinned every
|
|
131
|
+
cue to the same spot and rendered them one over the other — Media3 does the stacking in its WebVTT
|
|
132
|
+
*parser* (`line = -1 - i`) and has no equivalent pass for SubRip. A `SubtitleParser` for SubRip now
|
|
133
|
+
splits the cue timeline at every boundary and merges the cues active in each slice into a single
|
|
134
|
+
multi-line cue, ordered like WebVTT: the cue that started earliest sits at the bottom. This also
|
|
135
|
+
makes Android match the iOS output, which already stacked because sideloaded SRT is converted to
|
|
136
|
+
WebVTT there. Cues with explicit `{\anN}` positioning are left untouched.
|
|
137
|
+
- **Android:** selecting a `subtitleTrack` whose id is not among the available tracks no longer
|
|
138
|
+
leaves the previously selected track on screen. The cleared track-selection parameters were only
|
|
139
|
+
applied when a matching track was found, so an unmatched assignment silently did nothing; the
|
|
140
|
+
selection is now cleared and a warning is logged.
|
|
141
|
+
- **Android:** `subtitleStyle.bottomOffset` is reset to the default when it is omitted, instead of
|
|
142
|
+
keeping the value from a previously applied style.
|
|
143
|
+
|
|
144
|
+
## 0.1.1
|
|
145
|
+
|
|
146
|
+
### Fixed
|
|
147
|
+
|
|
148
|
+
- **Android:** `subtitleStyle.fontFamily` now resolves custom fonts bundled with the app, the same way
|
|
149
|
+
React Native resolves a `<Text>` component's `fontFamily`. It is looked up as an Android font
|
|
150
|
+
resource (`res/font`, where `expo-font`'s config plugin puts fonts) and then through React Native's
|
|
151
|
+
font manager, which covers the `assets/fonts/<name>.ttf` convention and fonts registered at runtime.
|
|
152
|
+
Previously only the built-in system families worked: `Typeface.create` silently fell back to the
|
|
153
|
+
default typeface for any bundled font, so `fontFamily` appeared to do nothing on Android while
|
|
154
|
+
working on iOS.
|
|
155
|
+
|
|
156
|
+
### Documentation
|
|
157
|
+
|
|
158
|
+
- Document font support and the silent-fallback behaviour for unresolved family names.
|
|
159
|
+
|
|
160
|
+
## 0.1.0
|
|
161
|
+
|
|
162
|
+
Initial release. Based on `expo-video` **56.1.4** (Expo SDK 56).
|
|
163
|
+
|
|
164
|
+
### Added
|
|
165
|
+
|
|
166
|
+
- **External (sideloaded) subtitles** via `VideoSource.subtitleTracks`. Attach WebVTT or SubRip
|
|
167
|
+
subtitle files (local or remote) to any source — most importantly progressive **MP4**, which,
|
|
168
|
+
unlike HLS/DASH manifests, cannot advertise its own subtitle renditions. Sideloaded tracks are
|
|
169
|
+
merged into the media and surface through `availableSubtitleTracks`, so they are selected with
|
|
170
|
+
`subtitleTrack` exactly like embedded tracks.
|
|
171
|
+
- Android: merged with `MediaItem.SubtitleConfiguration` (Media3 wraps them in a `MergingMediaSource`).
|
|
172
|
+
- iOS: merged into an `AVMutableComposition` as a `.text` track. SRT is converted to WebVTT, remote
|
|
173
|
+
files are cached locally first, and per-track time ranges are clamped to the video duration.
|
|
174
|
+
Applies to progressive, non-DRM sources on the asynchronous loading path.
|
|
175
|
+
- **Custom subtitle styling** via the `VideoView` `subtitleStyle` prop: `textColor`, `backgroundColor`,
|
|
176
|
+
`windowColor`, `fontSize`, `fontFamily`, `bold`, `edgeType`, `edgeColor`, and `bottomOffset`.
|
|
177
|
+
Applies to embedded and sideloaded tracks alike.
|
|
178
|
+
- Android: `CaptionStyleCompat` on the `PlayerView` subtitle view.
|
|
179
|
+
- iOS: `AVPlayerItem.textStyleRules`.
|
|
180
|
+
|
|
181
|
+
### Changed
|
|
182
|
+
|
|
183
|
+
- The Android `publication` block and the iOS prebuild artifacts are removed, so the modified
|
|
184
|
+
Kotlin and Swift are compiled from source instead of resolving a precompiled AAR/XCFramework.
|
package/FORK.md
CHANGED
|
@@ -5,9 +5,10 @@ and (b) pull a newer `expo-video` release into it **without losing the subtitle
|
|
|
5
5
|
|
|
6
6
|
- **Baseline:** `expo-video@56.1.4` (Expo SDK 56), as published on npm.
|
|
7
7
|
- **Native module name:** unchanged (`ExpoVideo`) — this is a drop-in replacement, not a coexisting package.
|
|
8
|
-
- **Design principle:** the fork is deliberately **surgical and additive**.
|
|
9
|
-
of the logic (
|
|
10
|
-
ones. Nothing upstream is rewritten
|
|
8
|
+
- **Design principle:** the fork is deliberately **surgical and additive**. 7 new source files hold
|
|
9
|
+
almost all of the logic (~1,200 lines); the 19 touched upstream files receive ~450 added lines and
|
|
10
|
+
only ~44 removed ones. Nothing upstream is rewritten — the removals are call-site signatures and a
|
|
11
|
+
handful of rewritten function bodies — so a version bump is a small, mechanical re-apply.
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
@@ -23,18 +24,20 @@ Measured against the published `expo-video@56.1.4` tarball. `+`/`-` are added/re
|
|
|
23
24
|
| `ios/Records/SubtitleStyle.swift` | 118 | Record for caption styling; hex→ARGB parsing; builds `[AVTextStyleRule]`. |
|
|
24
25
|
| `ios/VideoPlayerSubtitleSideload.swift` | 203 | Builds the `AVMutableComposition`, downloads remote subs, SRT→WebVTT converter. |
|
|
25
26
|
| `android/…/records/SubtitleSource.kt` | 54 | Record → `MediaItem.SubtitleConfiguration` + MIME resolution. |
|
|
26
|
-
| `android/…/records/SubtitleStyle.kt` |
|
|
27
|
-
| `android/…/utils/StackingSubtitleParser.kt` |
|
|
27
|
+
| `android/…/records/SubtitleStyle.kt` | 144 | Record → `CaptionStyleCompat`; hex colour parsing; font-family resolution (`res/font` → `ReactFontManager`); the `applyEmbeddedStyles` flag, which `SubtitleUtils` reads directly rather than `toCaptionStyle`. |
|
|
28
|
+
| `android/…/utils/StackingSubtitleParser.kt` | 300 | `SubtitleParser` for SubRip that segments the cue timeline and merges simultaneous cues into one stacked block, plus the `SubtitleParser.Factory` that routes SubRip to it. Assigns each cue a vertical slot it keeps for its whole time on screen — a finished cue's line is held blank (`\u200B`) so the cues above it do not drop. Merges through a `SpannableStringBuilder` so cue spans survive. |
|
|
29
|
+
| `android/…/utils/RoundedSubtitleBackground.kt` | 352 | Draws `subtitleStyle.backgroundRadius` as rounded boxes, which Media3 cannot do at all: it paints `backgroundColor` as a framework `BackgroundColorSpan` and `windowColor` with `canvas.drawRect`, neither takes a radius, and `SubtitlePainter`/`CanvasSubtitleOutput` are package-private final while `SubtitleView` is final. A second `SubtitleView` is inserted behind `PlayerView`'s own, fed from `Player.Listener.onCues`, drawing a `LineBackgroundSpan` per line. **Its `EDGE_TYPE_NONE` is load-bearing** — `SubtitlePainter` copies the cue text for an edge pass and draws both layouts when the edge type is outline/raised/depressed, which would paint the box twice and darken a semi-transparent colour. State hangs off the view's `tag`, never a map in the companion object; see the `find` KDoc for why even a `WeakHashMap` leaks here. |
|
|
28
30
|
| `FORK.md`, `LICENSE` | — | This guide; MIT licence (upstream copyright preserved). |
|
|
29
31
|
| `eslint.config.js` | 4 | Verbatim copy of `expo-module-scripts/templates/eslint.config.js`. **Recreate it if a sync drops it** — `expo-module configure` treats it as an *optional* template and only syncs it when it already exists, so without this file `npm run lint` dies with "ESLint couldn't find an eslint.config.js". |
|
|
30
32
|
| `.gitattributes` | 21 | Pins the working copy to LF. Git stores these files with LF, but a Windows checkout rewrites them to CRLF and the Prettier rule `npm run lint` enforces wants LF, which drowned the output in ~2800 "Delete `␍`" warnings. |
|
|
33
|
+
| `.prettierrc` | 7 | The Expo monorepo's Prettier options, which the sources were formatted with. `eslint-config-universe` turns the `prettier/prettier` rule *on* but supplies no options, and upstream inherits them from the monorepo root — a file that does not come along when the package is forked out on its own. Without this, Prettier falls back to its own defaults and reports 377 warnings against correctly formatted code. Only `printWidth` and `singleQuote` differ from Prettier 2's defaults today; the rest are written out because they are what upstream uses, and `trailingComma` guards against a bump to Prettier 3, whose default is `"all"`. |
|
|
31
34
|
|
|
32
35
|
### Modified — upstream files carrying fork edits (re-apply these after a sync)
|
|
33
36
|
|
|
34
37
|
| File | Δ | What to re-apply |
|
|
35
38
|
| --- | --- | --- |
|
|
36
39
|
| `src/VideoPlayer.types.ts` | +59 | `subtitleTracks?: SubtitleSource[]` on `VideoSourceObject`; the exported `SubtitleSource` type. |
|
|
37
|
-
| `src/VideoView.types.ts` | +
|
|
40
|
+
| `src/VideoView.types.ts` | +129 | `subtitleStyle?: SubtitleStyle` on `VideoViewProps`; `SubtitleStyle` + `SubtitleEdgeType` types. |
|
|
38
41
|
| `src/index.ts` | +2 | Export `SubtitleStyle`, `SubtitleEdgeType` (`SubtitleSource` rides on `export type *`). |
|
|
39
42
|
| `src/VideoPlayer.web.tsx` | +5 / −1 | Hoist `JSON.stringify(source)` out of the `useMemo` dependency list into a `sourceKey` const. No behaviour change — it was already recomputed every render — but `react-hooks/use-memo` rejects non-simple expressions in a dependency array, and it was the single lint **error** in the package. |
|
|
40
43
|
| `src/ts-declarations/react-native-assets.d.ts` | +22 / −1 | Replace upstream's `../../../expo-asset/…` reference (monorepo-only) with standalone `declare module` shims. **Always needed outside the Expo monorepo.** |
|
|
@@ -44,14 +47,16 @@ Measured against the published `expo-video@56.1.4` tarball. `+`/`-` are added/re
|
|
|
44
47
|
| `ios/VideoView.swift` | +8 | `subtitleStyle` property; forward it when `player` is (re)assigned. |
|
|
45
48
|
| `ios/VideoModule.swift` | +4 | `Prop("subtitleStyle")`. |
|
|
46
49
|
| `android/…/records/VideoSource.kt` | +9 / −2 | `subtitleTracks` field; `setSubtitleConfigurations(…)` in `toMediaItem()`; subtitle key in `toMediaId()`. |
|
|
47
|
-
| `android/…/utils/SubtitleUtils.kt` | +
|
|
48
|
-
| `android/…/VideoView.kt` | +
|
|
50
|
+
| `android/…/utils/SubtitleUtils.kt` | +92 / −21 | `configureSubtitleView(…, customStyle)` overload and a `styleProvider` on the captioning listener. Keeps the original behaviour when no custom style is set. Passes `context` to `toCaptionStyle` for font lookup. Drives `setApplyEmbeddedStyles` from `customStyle.applyEmbeddedStyles` (upstream hardcodes `false`). |
|
|
51
|
+
| `android/…/VideoView.kt` | +16 / −5 | `subtitleStyle` property; pass it at all 4 `configureSubtitleView` call sites + the captioning listener. |
|
|
49
52
|
| `android/…/VideoModule.kt` | +4 | `Prop("subtitleStyle")`. |
|
|
50
53
|
| `android/…/utils/DataSourceUtils.kt` | +5 | `setSubtitleParserFactory(ExpoVideoSubtitleParserFactory())` on the `DefaultMediaSourceFactory`. Note this file declares `package expo.modules.video` despite living in `utils/`, so the factory needs an explicit import. |
|
|
54
|
+
| `android/…/player/VideoPlayer.kt` | +13 / −2 | In `changeVideoView`, after `switchTargetView`: release the subtitle view the player is leaving and reconfigure the one it moves to. **Load-bearing for `backgroundRadius`** — that feature subscribes to the `Player` directly rather than riding on `PlayerView.setPlayer`, so a view that no longer drives the player keeps its subscription and goes on drawing stale cues. This is the choke point for every player move except entering fullscreen, which bypasses it (see `FullscreenPlayerActivity`). |
|
|
51
55
|
| `android/…/player/VideoPlayerSubtitles.kt` | +14 / −8 | Apply the cleared track-selection parameters when the requested subtitle id matches nothing, instead of only inside the `format?.let` block. |
|
|
52
|
-
| `android/…/FullscreenPlayerActivity.kt` | +
|
|
56
|
+
| `android/…/FullscreenPlayerActivity.kt` | +15 / −3 | Pass `videoView.subtitleStyle` at its 2 call sites + the captioning listener. Also release the originating `VideoView`'s subtitle view right after its own `switchTargetView` — this path bypasses `changeVideoView`, so without it the player carries two cue listeners for the whole time it is fullscreen — and release this activity's own in `onDestroy`. |
|
|
53
57
|
| `package.json` | — | Fork identity + build scripts — see §3. |
|
|
54
58
|
| `expo-module.config.json` | — | **Android `publication` block removed** — see §3. |
|
|
59
|
+
| `.npmignore` | +21 / −1 | A "Fork additions" block excluding the repo's own development config from the tarball: `.gitattributes`, `.prettierrc`, `eslint.config.js`, `tsconfig.all.json` and `*.tsbuildinfo`. Needed because the generated file only excludes hidden *directories* (`/.*/`), and because npm ignores `.gitignore` outright once an `.npmignore` exists — so the tsc build caches shipped despite git ignoring them. The `−1` drops the entry for `oxlint.config.mjs`, deleted in 0.2.0. |
|
|
55
60
|
| `README.md`, `CHANGELOG.md` | — | Fork docs; do not take upstream's. |
|
|
56
61
|
|
|
57
62
|
### Removed — upstream artifacts deliberately dropped
|
|
@@ -110,9 +115,10 @@ Then re-apply the fork:
|
|
|
110
115
|
(call-site signatures), `VideoPlayerItem.swift` (`isHls` hoist) and the ts-declarations shim.
|
|
111
116
|
7. **Remove the Android `publication` block** from `expo-module.config.json`.
|
|
112
117
|
8. **Restore the fork's `package.json`** (§3) and keep `README.md`, `CHANGELOG.md`, `LICENSE`,
|
|
113
|
-
`FORK.md`, `eslint.config.js` and `.
|
|
114
|
-
so the root-level files survive on their own — but confirm it, because a
|
|
115
|
-
breaks `npm run lint` in a way that reads like a tooling bug rather than
|
|
118
|
+
`FORK.md`, `eslint.config.js`, `.gitattributes` and `.prettierrc`. Step 3 only replaces
|
|
119
|
+
`src ios android plugin`, so the root-level files survive on their own — but confirm it, because a
|
|
120
|
+
missing `eslint.config.js` breaks `npm run lint` in a way that reads like a tooling bug rather than
|
|
121
|
+
a lost file, and a missing `.prettierrc` buries the output in warnings against correct code.
|
|
116
122
|
9. Update the baseline version in this file, the README, and add a `CHANGELOG.md` entry.
|
|
117
123
|
10. Verify with §5, then commit.
|
|
118
124
|
|
|
@@ -170,14 +176,23 @@ entry, in §1 of this file and in the README's intro line.
|
|
|
170
176
|
|
|
171
177
|
```bash
|
|
172
178
|
npm run typecheck # must be clean
|
|
173
|
-
npm run lint #
|
|
179
|
+
npm run lint # expect zero output: no errors and no warnings
|
|
174
180
|
npm pack --dry-run # expect build/, plugin/build/, LICENSE, native sources;
|
|
175
|
-
# NO node_modules, prebuilds, local-maven-repo
|
|
181
|
+
# NO node_modules, prebuilds, local-maven-repo;
|
|
182
|
+
# NO dev config (.prettierrc, eslint.config.js, *.tsbuildinfo) — see §1
|
|
176
183
|
```
|
|
177
184
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
185
|
+
The file count is a blunt but effective regression check: **254 files** as of 0.2.2. If a change moves
|
|
186
|
+
it, diff the list against the previous release and confirm every difference is intended —
|
|
187
|
+
`npm pack --dry-run --json` gives a machine-readable list. Both directions matter: an unexpected
|
|
188
|
+
*addition* means dev clutter leaked in, an unexpected *removal* means a consumer is missing something.
|
|
189
|
+
|
|
190
|
+
`npm run lint` depends on two root files that upstream does not carry, both described in §1:
|
|
191
|
+
`eslint.config.js` (without it ESLint refuses to run at all) and `.prettierrc` (without it Prettier
|
|
192
|
+
falls back to its own defaults and reports hundreds of warnings against correctly formatted code).
|
|
193
|
+
Neither is created by `expo-module configure`, so a sync that loses one breaks this step in a way
|
|
194
|
+
that reads like a tooling bug. A `prettier/prettier` warning after a sync is far more likely to mean
|
|
195
|
+
the config went missing than that the code is genuinely misformatted — check that first.
|
|
181
196
|
|
|
182
197
|
### Android — compiling the parser without a host app
|
|
183
198
|
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
The MIT License (MIT)
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|