fix(ios): fix sideloading external subtitles (#3690)
* fix(ios): fix subtitles side loading * update example * Update examples/basic/src/VideoPlayer.tsx Co-authored-by: Olivier Bouillet <62574056+freeboub@users.noreply.github.com> * Update examples/basic/src/VideoPlayer.tsx Co-authored-by: Olivier Bouillet <62574056+freeboub@users.noreply.github.com> --------- Co-authored-by: Olivier Bouillet <62574056+freeboub@users.noreply.github.com>
This commit is contained in:
parent
b5ccc48476
commit
efa1c52491
@ -134,8 +134,10 @@ class VideoPlayer extends Component {
|
|||||||
uri: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8',
|
uri: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: 'sintel with sideLoaded subtitles',
|
description: 'BigBugBunny sideLoaded subtitles',
|
||||||
uri: 'https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8', // this is sample video, my actual video file is MP4
|
// sideloaded subtitles wont work for streaming like HLS on ios
|
||||||
|
// mp4
|
||||||
|
uri: 'https://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4',
|
||||||
textTracks: [
|
textTracks: [
|
||||||
{
|
{
|
||||||
title: 'test',
|
title: 'test',
|
||||||
@ -195,7 +197,7 @@ class VideoPlayer extends Component {
|
|||||||
description: 'rtsp big bug bunny',
|
description: 'rtsp big bug bunny',
|
||||||
uri: 'rtsp://rtspstream:3cfa3c36a9c00f4aa38f3cd35816b287@zephyr.rtsp.stream/movie',
|
uri: 'rtsp://rtspstream:3cfa3c36a9c00f4aa38f3cd35816b287@zephyr.rtsp.stream/movie',
|
||||||
type: 'rtsp',
|
type: 'rtsp',
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// poster which can be displayed
|
// poster which can be displayed
|
||||||
@ -240,20 +242,20 @@ class VideoPlayer extends Component {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const position = this.calculateSeekerPosition();
|
const position = this.calculateSeekerPosition();
|
||||||
this.setSeekerPosition(position);
|
this.setSeekerPosition(position);
|
||||||
}, 1)
|
}, 1);
|
||||||
}
|
};
|
||||||
|
|
||||||
onProgress = (data: OnProgressData) => {
|
onProgress = (data: OnProgressData) => {
|
||||||
this.setState({currentTime: data.currentTime});
|
this.setState({currentTime: data.currentTime});
|
||||||
if (!this.state.seeking) {
|
if (!this.state.seeking) {
|
||||||
this.updateSeeker()
|
this.updateSeeker();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onSeek = (data: OnSeekData) => {
|
onSeek = (data: OnSeekData) => {
|
||||||
this.setState({currentTime: data.currentTime});
|
this.setState({currentTime: data.currentTime});
|
||||||
this.updateSeeker()
|
this.updateSeeker();
|
||||||
}
|
};
|
||||||
|
|
||||||
onVideoLoadStart = () => {
|
onVideoLoadStart = () => {
|
||||||
console.log('onVideoLoadStart');
|
console.log('onVideoLoadStart');
|
||||||
@ -363,11 +365,11 @@ class VideoPlayer extends Component {
|
|||||||
|
|
||||||
onPlaybackRateChange = (data: OnPlaybackRateChangeData) => {
|
onPlaybackRateChange = (data: OnPlaybackRateChangeData) => {
|
||||||
console.log('onPlaybackRateChange', data);
|
console.log('onPlaybackRateChange', data);
|
||||||
}
|
};
|
||||||
|
|
||||||
onPlaybackStateChanged = (data: OnPlaybackStateChangedData) => {
|
onPlaybackStateChanged = (data: OnPlaybackStateChangedData) => {
|
||||||
console.log('onPlaybackStateChanged', data);
|
console.log('onPlaybackStateChanged', data);
|
||||||
}
|
};
|
||||||
|
|
||||||
toggleFullscreen() {
|
toggleFullscreen() {
|
||||||
this.setState({fullscreen: !this.state.fullscreen});
|
this.setState({fullscreen: !this.state.fullscreen});
|
||||||
|
@ -246,7 +246,7 @@ enum RCTVideoUtils {
|
|||||||
static func getValidTextTracks(asset: AVAsset, assetOptions: NSDictionary?, mixComposition: AVMutableComposition,
|
static func getValidTextTracks(asset: AVAsset, assetOptions: NSDictionary?, mixComposition: AVMutableComposition,
|
||||||
textTracks: [TextTrack]?) async -> [TextTrack] {
|
textTracks: [TextTrack]?) async -> [TextTrack] {
|
||||||
var validTextTracks: [TextTrack] = []
|
var validTextTracks: [TextTrack] = []
|
||||||
var tracks: [[AVAssetTrack]] = []
|
var tracks: [([AVAssetTrack], AVURLAsset)] = []
|
||||||
|
|
||||||
let videoTracks = await RCTVideoAssetsUtils.getTracks(asset: asset, withMediaType: .video)
|
let videoTracks = await RCTVideoAssetsUtils.getTracks(asset: asset, withMediaType: .video)
|
||||||
guard let videoAsset = videoTracks?.first else { return validTextTracks }
|
guard let videoAsset = videoTracks?.first else { return validTextTracks }
|
||||||
@ -268,23 +268,20 @@ enum RCTVideoUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let track = await RCTVideoAssetsUtils.getTracks(asset: textURLAsset, withMediaType: .text) {
|
if let track = await RCTVideoAssetsUtils.getTracks(asset: textURLAsset, withMediaType: .text) {
|
||||||
tracks.append(track)
|
tracks.append((track, textURLAsset))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0 ..< tracks.count {
|
for (index, tracksPair) in tracks.enumerated() {
|
||||||
guard let track = tracks[i].first else { continue } // fix when there's no textTrackAsset
|
let (tracks, trackAsset) = tracksPair
|
||||||
|
guard let track = tracks.first else { continue } // fix when there's no textTrackAsset
|
||||||
|
|
||||||
let textCompTrack: AVMutableCompositionTrack! = mixComposition.addMutableTrack(withMediaType: AVMediaType.text,
|
let textCompTrack: AVMutableCompositionTrack! = mixComposition.addMutableTrack(withMediaType: AVMediaType.text,
|
||||||
preferredTrackID: kCMPersistentTrackID_Invalid)
|
preferredTrackID: kCMPersistentTrackID_Invalid)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try textCompTrack.insertTimeRange(
|
try textCompTrack.insertTimeRange(CMTimeRangeMake(start: .zero, duration: trackAsset.duration), of: track, at: .zero)
|
||||||
CMTimeRangeMake(start: .zero, duration: videoAsset.timeRange.duration),
|
validTextTracks.append(textTracks[index])
|
||||||
of: track,
|
|
||||||
at: .zero
|
|
||||||
)
|
|
||||||
validTextTracks.append(textTracks[i])
|
|
||||||
} catch {
|
} catch {
|
||||||
// TODO: upgrade error by call some props callback to better inform user
|
// TODO: upgrade error by call some props callback to better inform user
|
||||||
print("Error occurred on textTrack insert attempt: \(error.localizedDescription)")
|
print("Error occurred on textTrack insert attempt: \(error.localizedDescription)")
|
||||||
|
Loading…
Reference in New Issue
Block a user