chore(android): refactor side loaded text tracks (#3754)

* perf: ensure we do not provide callback to native if no callback provided from app

* chore: rework bufferConfig to make it more generic and reduce ReactExoplayerView code size

* chore(android): refactor external text tracks management.

Split parsing and tracks handling

* chore: fix linter
This commit is contained in:
Olivier Bouillet 2024-05-11 18:57:59 +02:00 committed by GitHub
parent 3f63fd076d
commit efb338ee2a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 75 additions and 19 deletions

View File

@ -0,0 +1,34 @@
package com.brentvatne.common.api
import android.net.Uri
import com.brentvatne.common.toolbox.ReactBridgeUtils
import com.facebook.react.bridge.ReadableMap
/**
* Class representing a sideLoaded text track from application
* Do you use player import in this class
*/
class SideLoadedTextTrack {
var language: String? = null
var title: String? = null
var uri: Uri = Uri.EMPTY
var type: String? = null
companion object {
val SIDELOAD_TEXT_TRACK_LANGUAGE = "language"
val SIDELOAD_TEXT_TRACK_TITLE = "title"
val SIDELOAD_TEXT_TRACK_URI = "uri"
val SIDELOAD_TEXT_TRACK_TYPE = "type"
fun parse(src: ReadableMap?): SideLoadedTextTrack {
val sideLoadedTextTrack = SideLoadedTextTrack()
if (src == null) {
return sideLoadedTextTrack
}
sideLoadedTextTrack.language = ReactBridgeUtils.safeGetString(src, SIDELOAD_TEXT_TRACK_LANGUAGE)
sideLoadedTextTrack.title = ReactBridgeUtils.safeGetString(src, SIDELOAD_TEXT_TRACK_TITLE, "")
sideLoadedTextTrack.uri = Uri.parse(ReactBridgeUtils.safeGetString(src, SIDELOAD_TEXT_TRACK_URI, ""))
sideLoadedTextTrack.type = ReactBridgeUtils.safeGetString(src, SIDELOAD_TEXT_TRACK_TYPE, "")
return sideLoadedTextTrack
}
}
}

View File

@ -0,0 +1,27 @@
package com.brentvatne.common.api
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.bridge.ReadableMap
/**
* Class representing a list of sideLoaded text track from application
* Do you use player import in this class
*/
class SideLoadedTextTrackList {
var tracks = ArrayList<SideLoadedTextTrack>()
companion object {
fun parse(src: ReadableArray?): SideLoadedTextTrackList? {
if (src == null) {
return null
}
var sideLoadedTextTrackList = SideLoadedTextTrackList()
for (i in 0 until src.size()) {
val textTrack: ReadableMap = src.getMap(i)
sideLoadedTextTrackList.tracks.add(SideLoadedTextTrack.parse(textTrack))
}
return sideLoadedTextTrackList
}
}
}

View File

@ -106,6 +106,8 @@ import androidx.media3.ui.LegacyPlayerControlView;
import com.brentvatne.common.api.BufferConfig; import com.brentvatne.common.api.BufferConfig;
import com.brentvatne.common.api.ResizeMode; import com.brentvatne.common.api.ResizeMode;
import com.brentvatne.common.api.SideLoadedTextTrack;
import com.brentvatne.common.api.SideLoadedTextTrackList;
import com.brentvatne.common.api.SubtitleStyle; import com.brentvatne.common.api.SubtitleStyle;
import com.brentvatne.common.api.TimedMetadata; import com.brentvatne.common.api.TimedMetadata;
import com.brentvatne.common.api.Track; import com.brentvatne.common.api.Track;
@ -117,8 +119,6 @@ import com.brentvatne.react.R;
import com.brentvatne.receiver.AudioBecomingNoisyReceiver; import com.brentvatne.receiver.AudioBecomingNoisyReceiver;
import com.brentvatne.receiver.BecomingNoisyListener; import com.brentvatne.receiver.BecomingNoisyListener;
import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ThemedReactContext;
import com.google.ads.interactivemedia.v3.api.AdError; import com.google.ads.interactivemedia.v3.api.AdError;
@ -220,7 +220,7 @@ public class ReactExoplayerView extends FrameLayout implements
private String videoTrackValue; private String videoTrackValue;
private String textTrackType; private String textTrackType;
private String textTrackValue; private String textTrackValue;
private ReadableArray textTracks; private SideLoadedTextTrackList textTracks;
private boolean disableFocus; private boolean disableFocus;
private boolean focusable = true; private boolean focusable = true;
private boolean disableBuffering; private boolean disableBuffering;
@ -995,18 +995,13 @@ public class ReactExoplayerView extends FrameLayout implements
return textSources; return textSources;
} }
for (int i = 0; i < textTracks.size(); ++i) { for (SideLoadedTextTrack track : textTracks.getTracks()) {
ReadableMap textTrack = textTracks.getMap(i); MediaSource textSource = buildTextSource(track.getTitle(),
String language = textTrack.getString("language"); track.getUri(),
String title = textTrack.hasKey("title") track.getType(),
? textTrack.getString("title") : language + " " + i; track.getLanguage());
Uri uri = Uri.parse(textTrack.getString("uri"));
MediaSource textSource = buildTextSource(title, uri, textTrack.getString("type"),
language);
if (textSource != null) {
textSources.add(textSource); textSources.add(textSource);
} }
}
return textSources; return textSources;
} }
@ -1718,7 +1713,7 @@ public class ReactExoplayerView extends FrameLayout implements
} }
} }
public void setTextTracks(ReadableArray textTracks) { public void setTextTracks(SideLoadedTextTrackList textTracks) {
this.textTracks = textTracks; this.textTracks = textTracks;
reloadSource(); reloadSource();
} }

View File

@ -14,6 +14,7 @@ import androidx.media3.exoplayer.DefaultLoadControl;
import com.brentvatne.common.api.BufferConfig; import com.brentvatne.common.api.BufferConfig;
import com.brentvatne.common.api.ResizeMode; import com.brentvatne.common.api.ResizeMode;
import com.brentvatne.common.api.SideLoadedTextTrackList;
import com.brentvatne.common.api.SubtitleStyle; import com.brentvatne.common.api.SubtitleStyle;
import com.brentvatne.common.react.VideoEventEmitter; import com.brentvatne.common.react.VideoEventEmitter;
import com.brentvatne.common.toolbox.DebugLog; import com.brentvatne.common.toolbox.DebugLog;
@ -309,7 +310,8 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
@ReactProp(name = PROP_TEXT_TRACKS) @ReactProp(name = PROP_TEXT_TRACKS)
public void setPropTextTracks(final ReactExoplayerView videoView, public void setPropTextTracks(final ReactExoplayerView videoView,
@Nullable ReadableArray textTracks) { @Nullable ReadableArray textTracks) {
videoView.setTextTracks(textTracks); SideLoadedTextTrackList sideLoadedTextTracks = SideLoadedTextTrackList.Companion.parse(textTracks);
videoView.setTextTracks(sideLoadedTextTracks);
} }
@ReactProp(name = PROP_PAUSED, defaultBoolean = false) @ReactProp(name = PROP_PAUSED, defaultBoolean = false)

View File

@ -72,9 +72,7 @@ class VideoPlaybackService : MediaSessionService() {
// Callbacks // Callbacks
override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? { override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? = null
return null
}
override fun onBind(intent: Intent?): IBinder { override fun onBind(intent: Intent?): IBinder {
super.onBind(intent) super.onBind(intent)