feat: improve demo app and some optimizations for iOS

This commit is contained in:
Brian Sztamfater 2023-05-05 15:57:49 -03:00
parent 6640e69a81
commit 4496ad19e3
10 changed files with 96 additions and 22 deletions

View File

@ -2,6 +2,7 @@ package com.transparentvideo;
import android.graphics.Color; import android.graphics.Color;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -14,6 +15,7 @@ import java.util.Dictionary;
public class TransparentVideoViewManager extends SimpleViewManager<View> { public class TransparentVideoViewManager extends SimpleViewManager<View> {
public static final String REACT_CLASS = "TransparentVideoView"; public static final String REACT_CLASS = "TransparentVideoView";
private AlphaMovieView alphaMovieView;
@Override @Override
@NonNull @NonNull
@ -29,6 +31,11 @@ public class TransparentVideoViewManager extends SimpleViewManager<View> {
@ReactProp(name = "src") @ReactProp(name = "src")
public void setSrc(View view, ReadableMap src) { public void setSrc(View view, ReadableMap src) {
if (this.alphaMovieView == null) {
alphaMovieView = new AlphaMovieView(view.getContext(), null); //new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
alphaMovieView.setAutoPlayAfterResume(true);
alphaMovieView.setVideoByUrl(src.getString("uri"));
}
view.setBackgroundColor(Color.BLUE); view.setBackgroundColor(Color.BLUE);
} }
} }

BIN
example/assets/videos/1.mp4 Normal file

Binary file not shown.

BIN
example/assets/videos/2.mp4 Normal file

Binary file not shown.

BIN
example/assets/videos/3.mp4 Normal file

Binary file not shown.

BIN
example/assets/videos/4.mp4 Normal file

Binary file not shown.

Binary file not shown.

View File

@ -145,7 +145,6 @@
8FF5F75A1315DCD7F71FC708 /* Pods-TransparentVideoExample-TransparentVideoExampleTests.debug.xcconfig */, 8FF5F75A1315DCD7F71FC708 /* Pods-TransparentVideoExample-TransparentVideoExampleTests.debug.xcconfig */,
2A14A34D05389C0ADABA2876 /* Pods-TransparentVideoExample-TransparentVideoExampleTests.release.xcconfig */, 2A14A34D05389C0ADABA2876 /* Pods-TransparentVideoExample-TransparentVideoExampleTests.release.xcconfig */,
); );
name = Pods;
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -485,6 +484,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 37DHY4JC9T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = TransparentVideoExample/Info.plist; INFOPLIST_FILE = TransparentVideoExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@ -511,6 +511,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 37DHY4JC9T;
INFOPLIST_FILE = TransparentVideoExample/Info.plist; INFOPLIST_FILE = TransparentVideoExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",

View File

@ -3,8 +3,10 @@ import React, { useEffect, useState } from 'react';
import { StyleSheet, View } from 'react-native'; import { StyleSheet, View } from 'react-native';
import TransparentVideo from 'react-native-transparent-video'; import TransparentVideo from 'react-native-transparent-video';
const video1 = require('../assets/videos/background.mp4'); const video1 = require('../assets/videos/1.mp4');
const video2 = require('../assets/videos/playdoh-bat.mp4'); const video2 = require('../assets/videos/2.mp4');
const video3 = require('../assets/videos/3.mp4');
const video4 = require('../assets/videos/4.mp4');
export default () => { export default () => {
const [background, setBackground] = useState('blue'); const [background, setBackground] = useState('blue');
@ -31,6 +33,8 @@ export default () => {
<View style={{ ...styles.container, ...{ backgroundColor: background } }}> <View style={{ ...styles.container, ...{ backgroundColor: background } }}>
<TransparentVideo source={video1} style={styles.video1} /> <TransparentVideo source={video1} style={styles.video1} />
<TransparentVideo source={video2} style={styles.video2} /> <TransparentVideo source={video2} style={styles.video2} />
<TransparentVideo source={video3} style={styles.video3} />
<TransparentVideo source={video4} style={styles.video4} />
</View> </View>
); );
}; };
@ -56,4 +60,20 @@ const styles = StyleSheet.create({
bottom: 0, bottom: 0,
zIndex: 1, zIndex: 1,
}, },
video3: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: 2,
},
video4: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: 3,
},
}); });

View File

@ -55,30 +55,76 @@ class TransparentVideoView : UIView {
} }
// Load our player item // Load our player item
let playerItem = createTransparentItem(url: itemUrl) loadItem(url: itemUrl)
self.playerView!.loadPlayerItem(playerItem) { result in
switch result {
case .failure(let error):
return print("Something went wrong when loading our video", error)
case .success(let player):
// Finally, we can start playing
player.play()
}
}
} }
// MARK: - Player Item Configuration // MARK: - Player Item Configuration
func createTransparentItem(url: URL) -> AVPlayerItem { private func loadItem(url: URL) {
setUpAsset(with: url) { [weak self] (asset: AVAsset) in
self?.setUpPlayerItem(with: asset)
}
}
private func setUpAsset(with url: URL, completion: ((_ asset: AVAsset) -> Void)?) {
let asset = AVAsset(url: url) let asset = AVAsset(url: url)
let playerItem = AVPlayerItem(asset: asset) asset.loadValuesAsynchronously(forKeys: ["metadata"]) {
// Set the video so that seeking also renders with transparency var error: NSError? = nil
playerItem.seekingWaitsForVideoCompositionRendering = true let status = asset.statusOfValue(forKey: "metadata", error: &error)
// Apply a video composition (which applies our custom filter) switch status {
playerItem.videoComposition = createVideoComposition(for: asset) case .loaded:
return playerItem completion?(asset)
case .failed:
print(".failed")
case .cancelled:
print(".cancelled")
default:
print("default")
}
}
}
private func setUpPlayerItem(with asset: AVAsset) {
DispatchQueue.main.async { [weak self] in
let playerItem = AVPlayerItem(asset: asset)
//playerItem.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), options: [.old, .new], context: nil)
playerItem.seekingWaitsForVideoCompositionRendering = true
// Apply a video composition (which applies our custom filter)
playerItem.videoComposition = self?.createVideoComposition(for: asset)
self?.playerView!.loadPlayerItem(playerItem) { result in
switch result {
case .failure(let error):
return print("Something went wrong when loading our video", error)
case .success(let player):
// Finally, we can start playing
player.play()
}
}
}
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == #keyPath(AVPlayerItem.status) {
let status: AVPlayerItem.Status
if let statusNumber = change?[.newKey] as? NSNumber {
status = AVPlayerItem.Status(rawValue: statusNumber.intValue)!
} else {
status = .unknown
}
// Switch over status value
switch status {
case .readyToPlay:
print(".readyToPlay")
case .failed:
print(".failed")
case .unknown:
print(".unknown")
@unknown default:
print("@unknown default")
}
}
} }
func createVideoComposition(for asset: AVAsset) -> AVVideoComposition { func createVideoComposition(for asset: AVAsset) -> AVVideoComposition {