added video api support ios
This commit is contained in:
parent
208752d58e
commit
63211b5c6d
|
@ -23,8 +23,7 @@
|
||||||
"mediapipe/objc/testing/app/BUILD"
|
"mediapipe/objc/testing/app/BUILD"
|
||||||
],
|
],
|
||||||
"buildTargets" : [
|
"buildTargets" : [
|
||||||
"//mediapipe/examples/ios/posetracking-lindera/PoseTrackingLindera:posetracking-lindera",
|
"//mediapipe/examples/ios/posetracking-lindera/PoseTrackingLindera:posetracking-lindera"
|
||||||
"//mediapipe/swift/solutions/lindera:lindera"
|
|
||||||
],
|
],
|
||||||
"optionSet" : {
|
"optionSet" : {
|
||||||
"BazelBuildOptionsDebug" : {
|
"BazelBuildOptionsDebug" : {
|
||||||
|
|
|
@ -12,7 +12,7 @@ MIN_IOS_VERSION = "14.0"
|
||||||
swift_library(
|
swift_library(
|
||||||
name = "lindera_app_lib",
|
name = "lindera_app_lib",
|
||||||
srcs = glob(["**/*.swift"]),
|
srcs = glob(["**/*.swift"]),
|
||||||
data =[
|
data = [
|
||||||
"Base.lproj/LaunchScreen.storyboard",
|
"Base.lproj/LaunchScreen.storyboard",
|
||||||
"Base.lproj/Main.storyboard",
|
"Base.lproj/Main.storyboard",
|
||||||
],
|
],
|
||||||
|
@ -62,7 +62,7 @@ ios_application(
|
||||||
"ipad",
|
"ipad",
|
||||||
],
|
],
|
||||||
infoplists = [
|
infoplists = [
|
||||||
"Info.plist",
|
"Infobazel.plist",
|
||||||
"//mediapipe/examples/ios/common:Info.plist",
|
"//mediapipe/examples/ios/common:Info.plist",
|
||||||
],
|
],
|
||||||
linkopts = [
|
linkopts = [
|
||||||
|
|
|
@ -56,6 +56,38 @@
|
||||||
<color key="textColor" systemColor="secondarySystemGroupedBackgroundColor"/>
|
<color key="textColor" systemColor="secondarySystemGroupedBackgroundColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
|
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xio-lL-zFK">
|
||||||
|
<rect key="frame" x="20" y="133" width="374" height="212"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yeq-1E-9PL">
|
||||||
|
<rect key="frame" x="8" y="104" width="151" height="43"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<state key="normal" title="Button"/>
|
||||||
|
<buttonConfiguration key="configuration" style="gray" title="Start Camera"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="startCamera" destination="BYZ-38-t0r" eventType="touchDown" id="bJ0-NK-Tiy"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Please Select Input Source" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qIp-Q6-AgF">
|
||||||
|
<rect key="frame" x="78" y="8" width="218" height="58"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SV7-hA-BsP">
|
||||||
|
<rect key="frame" x="215" y="104" width="151" height="43"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<state key="normal" title="Button"/>
|
||||||
|
<buttonConfiguration key="configuration" style="gray" title="Pick Video"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="pickVideo" destination="BYZ-38-t0r" eventType="touchDown" id="YSl-m6-lbI"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
|
</view>
|
||||||
</subviews>
|
</subviews>
|
||||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
|
@ -63,8 +95,10 @@
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="chooseModelButton" destination="oaC-Ax-V0a" id="Knp-ll-Zgu"/>
|
<outlet property="chooseModelButton" destination="oaC-Ax-V0a" id="Knp-ll-Zgu"/>
|
||||||
<outlet property="fpsLabel" destination="hSQ-so-ykH" id="sw5-ik-ro9"/>
|
<outlet property="fpsLabel" destination="hSQ-so-ykH" id="sw5-ik-ro9"/>
|
||||||
|
<outlet property="inputSourceView" destination="xio-lL-zFK" id="uiz-Te-v97"/>
|
||||||
<outlet property="liveView" destination="8bC-Xf-vdC" id="COw-5j-lAL"/>
|
<outlet property="liveView" destination="8bC-Xf-vdC" id="COw-5j-lAL"/>
|
||||||
<outlet property="showLandmarksButton" destination="dv5-h1-tjP" id="xXW-UG-aSR"/>
|
<outlet property="showLandmarksButton" destination="dv5-h1-tjP" id="xXW-UG-aSR"/>
|
||||||
|
<outlet property="startCameraButton" destination="yeq-1E-9PL" id="D90-1U-dYK"/>
|
||||||
<outlet property="titleview" destination="1BO-kg-lOt" id="uP4-0G-Gix"/>
|
<outlet property="titleview" destination="1BO-kg-lOt" id="uP4-0G-Gix"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
|
||||||
|
<key>UIApplicationSceneManifest</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>UIApplicationSupportsMultipleScenes</key>
|
||||||
|
<false/>
|
||||||
|
<key>MainViewController</key>
|
||||||
|
<string>ViewController</string>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -7,9 +7,34 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import LinderaDetection
|
import LinderaDetection
|
||||||
//import LinderaDetection
|
//import LinderaDetection
|
||||||
|
import PhotosUI
|
||||||
|
|
||||||
|
class ViewController: UIViewController, PHPickerViewControllerDelegate {
|
||||||
|
|
||||||
|
// Video Picker
|
||||||
|
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
|
||||||
|
|
||||||
|
for result in results {
|
||||||
|
result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier){url,err in
|
||||||
|
if let url = url {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
[weak self] in
|
||||||
|
|
||||||
class ViewController: UIViewController {
|
picker.dismiss(animated: true)
|
||||||
|
self?.inputSourceView.isHidden = true
|
||||||
|
|
||||||
|
}
|
||||||
|
let asset = AVAsset(url: url)
|
||||||
|
self.lindera.startVideo(asset: asset)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//MARK: - UI Elements
|
//MARK: - UI Elements
|
||||||
|
|
||||||
|
@ -17,11 +42,30 @@ class ViewController: UIViewController {
|
||||||
@IBOutlet var liveView : UIView!
|
@IBOutlet var liveView : UIView!
|
||||||
@IBOutlet var showLandmarksButton: UIButton!
|
@IBOutlet var showLandmarksButton: UIButton!
|
||||||
@IBOutlet var chooseModelButton: UIButton!
|
@IBOutlet var chooseModelButton: UIButton!
|
||||||
|
@IBOutlet var startCameraButton: UIButton!
|
||||||
@IBOutlet var titleview: UIView!
|
@IBOutlet var titleview: UIView!
|
||||||
@IBOutlet var fpsLabel: UILabel!
|
@IBOutlet var fpsLabel: UILabel!
|
||||||
|
@IBOutlet var inputSourceView: UIView!
|
||||||
|
|
||||||
//MARK: - UI Actions
|
//MARK: - UI Actions
|
||||||
|
@IBAction func startCamera(){
|
||||||
|
lindera.startCamera()
|
||||||
|
inputSourceView.isHidden = true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func pickVideo(){
|
||||||
|
var configuration = PHPickerConfiguration(photoLibrary: .shared())
|
||||||
|
let filter = PHPickerFilter.any(of: [ .videos])
|
||||||
|
configuration.filter = filter
|
||||||
|
configuration.selectionLimit = 1
|
||||||
|
let picker = PHPickerViewController(configuration: configuration)
|
||||||
|
picker.delegate = self
|
||||||
|
present(picker, animated: true)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@IBAction func setModelComplexity(){
|
@IBAction func setModelComplexity(){
|
||||||
let alert = UIAlertController(
|
let alert = UIAlertController(
|
||||||
|
@ -150,12 +194,16 @@ class ViewController: UIViewController {
|
||||||
// Otherwise they are hidden
|
// Otherwise they are hidden
|
||||||
self.liveView.bringSubviewToFront(titleview)
|
self.liveView.bringSubviewToFront(titleview)
|
||||||
self.liveView.bringSubviewToFront(fpsLabel)
|
self.liveView.bringSubviewToFront(fpsLabel)
|
||||||
|
self.liveView.bringSubviewToFront(inputSourceView)
|
||||||
// Make the Landmarks and Model button text reflect the state in lindera object
|
// Make the Landmarks and Model button text reflect the state in lindera object
|
||||||
updateLandmarksButtonText()
|
updateLandmarksButtonText()
|
||||||
updateModelButtonText()
|
updateModelButtonText()
|
||||||
|
|
||||||
lindera.startCamera()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
#if arch(arm64)
|
#if arch(arm64)
|
||||||
import MPPoseTracking
|
import MPPoseTracking
|
||||||
|
import AVFoundation
|
||||||
|
|
||||||
|
public enum InputSource {
|
||||||
|
case CAMERA,VIDEO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// A helper class to run the Pose Tracking API
|
/// A helper class to run the Pose Tracking API
|
||||||
|
@ -20,7 +26,45 @@ public final class Lindera{
|
||||||
public func setFpsDelegate(fpsDelegate: @escaping (_ fps:Double)->Void){
|
public func setFpsDelegate(fpsDelegate: @escaping (_ fps:Double)->Void){
|
||||||
fpsHelper.onFpsUpdate = fpsDelegate;
|
fpsHelper.onFpsUpdate = fpsDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func startVideo(asset:AVAsset){
|
||||||
|
self.videoSource = MPPPlayerInputSource(avAsset: asset)
|
||||||
|
self.videoSource.setDelegate(self.poseTracking, queue: self.poseTracking.videoQueue)
|
||||||
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
|
||||||
|
if let self = self {
|
||||||
|
// set our rendering layer frame according to cameraView boundry
|
||||||
|
self.poseTracking.renderer.layer.frame = self.cameraView.layer.bounds
|
||||||
|
// attach render CALayer on cameraView to render output to
|
||||||
|
self.cameraView.layer.addSublayer(self.poseTracking.renderer.layer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.poseTracking.videoQueue.async(execute:{ [weak self] in
|
||||||
|
self?.videoSource.start()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setInputSource(inputSource:InputSource){
|
||||||
|
if (self.inputSource==inputSource) {return}
|
||||||
|
switch(inputSource){
|
||||||
|
|
||||||
|
case .CAMERA:
|
||||||
|
self.cameraSource.setDelegate(self.poseTracking, queue: self.poseTracking.videoQueue)
|
||||||
|
break
|
||||||
|
|
||||||
|
case .VIDEO:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
self.inputSource = inputSource
|
||||||
|
|
||||||
|
}
|
||||||
// Get the camera UI View that may contain landmarks drawing
|
// Get the camera UI View that may contain landmarks drawing
|
||||||
public var cameraView: UIView {
|
public var cameraView: UIView {
|
||||||
return self.linderaExerciseSession
|
return self.linderaExerciseSession
|
||||||
|
@ -57,6 +101,7 @@ public final class Lindera{
|
||||||
startPoseTracking()
|
startPoseTracking()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public func startCamera(_ completion: ((Result<Void, Error>) -> Void)? = nil) {
|
public func startCamera(_ completion: ((Result<Void, Error>) -> Void)? = nil) {
|
||||||
// set our rendering layer frame according to cameraView boundry
|
// set our rendering layer frame according to cameraView boundry
|
||||||
|
@ -182,8 +227,9 @@ public final class Lindera{
|
||||||
|
|
||||||
// attach Mediapipe camera helper to our class
|
// attach Mediapipe camera helper to our class
|
||||||
let cameraSource = MPPCameraInputSource()
|
let cameraSource = MPPCameraInputSource()
|
||||||
|
var videoSource = MPPPlayerInputSource()
|
||||||
|
|
||||||
|
var inputSource:InputSource = InputSource.CAMERA
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user