Browse Source

avplayer

master
Marco Schmickler 9 years ago
parent
commit
b7d6eb2358
  1. 1
      Podfile
  2. 27
      kplayer.xcodeproj/project.pbxproj
  3. 65
      kplayer/Base.lproj/Main.storyboard
  4. 2
      kplayer/core/NetworkManager.swift
  5. 449
      kplayer/detail/AVPlayerController.swift
  6. 82
      kplayer/detail/DetailViewController.swift
  7. 70
      kplayer/detail/VideoPlayerController.swift
  8. 50
      kplayer/master/MasterViewController.swift
  9. 59
      kplayer/video/KBMPlayer.swift

1
Podfile

@ -15,6 +15,7 @@ target 'kplayer' do
pod 'HanekeSwift', :git => 'https://github.com/jasonnoahchoi/HanekeSwift', :branch => 'swift3' pod 'HanekeSwift', :git => 'https://github.com/jasonnoahchoi/HanekeSwift', :branch => 'swift3'
pod 'Nimbus/Photos' pod 'Nimbus/Photos'
pod 'Nimbus/PagingScrollView' pod 'Nimbus/PagingScrollView'
pod 'BMPlayer'
#pod 'AFNetworking', '~>2.1' #pod 'AFNetworking', '~>2.1'
#pod 'Dollar', '6.1.0' #pod 'Dollar', '6.1.0'
#pod 'Cent', '6.0.3' #pod 'Cent', '6.0.3'

27
kplayer.xcodeproj/project.pbxproj

@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1C7361D2B6E0AE689FAAF4F4 /* AVPlayerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736C7FFBDAC665AE04CB65 /* AVPlayerController.swift */; };
1C73631EACF56BABD3B2BCFB /* LayoutTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736BC4450890C45F8FBC63 /* LayoutTools.swift */; }; 1C73631EACF56BABD3B2BCFB /* LayoutTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736BC4450890C45F8FBC63 /* LayoutTools.swift */; };
1C73635138BBD2BB480A308F /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C736777456388CA571DA17B /* MediaPlayer.framework */; }; 1C73635138BBD2BB480A308F /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C736777456388CA571DA17B /* MediaPlayer.framework */; };
1C73640D928DE56D35175D39 /* UploadOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736260E748CF136FF37EA7 /* UploadOperation.swift */; }; 1C73640D928DE56D35175D39 /* UploadOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736260E748CF136FF37EA7 /* UploadOperation.swift */; };
@ -22,6 +23,7 @@
1C73688D13E5A804880C8768 /* UIImageExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736DCCE3AA9993E15F7652 /* UIImageExtension.swift */; }; 1C73688D13E5A804880C8768 /* UIImageExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736DCCE3AA9993E15F7652 /* UIImageExtension.swift */; };
1C73691A9C7174E0C6B57267 /* stringutil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736B794396F2E50387B8F2 /* stringutil.swift */; }; 1C73691A9C7174E0C6B57267 /* stringutil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736B794396F2E50387B8F2 /* stringutil.swift */; };
1C73693A1334A7792856FC58 /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73611D226B48C24DB37535 /* MasterViewController.swift */; }; 1C73693A1334A7792856FC58 /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73611D226B48C24DB37535 /* MasterViewController.swift */; };
1C7369763AB6C73472E11B55 /* KBMPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736D981F8315FFD7D40695 /* KBMPlayer.swift */; };
1C7369ABC44CFB530EA71FB6 /* HeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */; }; 1C7369ABC44CFB530EA71FB6 /* HeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */; };
1C736A5FA5BA53B2597F2ED7 /* Kirschkeks-256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C736059262A57AADE6AB761 /* Kirschkeks-256x256.png */; }; 1C736A5FA5BA53B2597F2ED7 /* Kirschkeks-256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C736059262A57AADE6AB761 /* Kirschkeks-256x256.png */; };
1C736D16E81BA1FB325200E0 /* HanekeFetchOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7360744ABACC3557D05760 /* HanekeFetchOperation.swift */; }; 1C736D16E81BA1FB325200E0 /* HanekeFetchOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7360744ABACC3557D05760 /* HanekeFetchOperation.swift */; };
@ -67,6 +69,8 @@
1C7369F53095B7A4D65679C2 /* DetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = "<group>"; }; 1C7369F53095B7A4D65679C2 /* DetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = "<group>"; };
1C736B794396F2E50387B8F2 /* stringutil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = stringutil.swift; sourceTree = "<group>"; }; 1C736B794396F2E50387B8F2 /* stringutil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = stringutil.swift; sourceTree = "<group>"; };
1C736BC4450890C45F8FBC63 /* LayoutTools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutTools.swift; sourceTree = "<group>"; }; 1C736BC4450890C45F8FBC63 /* LayoutTools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutTools.swift; sourceTree = "<group>"; };
1C736C7FFBDAC665AE04CB65 /* AVPlayerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AVPlayerController.swift; sourceTree = "<group>"; };
1C736D981F8315FFD7D40695 /* KBMPlayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KBMPlayer.swift; sourceTree = "<group>"; };
1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderCell.swift; sourceTree = "<group>"; }; 1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderCell.swift; sourceTree = "<group>"; };
1C736DCCE3AA9993E15F7652 /* UIImageExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtension.swift; sourceTree = "<group>"; }; 1C736DCCE3AA9993E15F7652 /* UIImageExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtension.swift; sourceTree = "<group>"; };
1C736E3BE8EC464D6F5DC8FA /* scratch.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = scratch.txt; sourceTree = "<group>"; }; 1C736E3BE8EC464D6F5DC8FA /* scratch.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = scratch.txt; sourceTree = "<group>"; };
@ -113,6 +117,7 @@
1C736069C214E9522BB1BD97 /* ItemCell.swift */, 1C736069C214E9522BB1BD97 /* ItemCell.swift */,
1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */, 1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */,
1C7369F53095B7A4D65679C2 /* DetailViewController.swift */, 1C7369F53095B7A4D65679C2 /* DetailViewController.swift */,
1C736C7FFBDAC665AE04CB65 /* AVPlayerController.swift */,
); );
path = detail; path = detail;
sourceTree = "<group>"; sourceTree = "<group>";
@ -160,6 +165,14 @@
path = core; path = core;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
1C736F3946A38499113D351A /* video */ = {
isa = PBXGroup;
children = (
1C736D981F8315FFD7D40695 /* KBMPlayer.swift */,
);
path = video;
sourceTree = "<group>";
};
8052F5B3AAC2535E5C08A529 /* Pods */ = { 8052F5B3AAC2535E5C08A529 /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -214,6 +227,7 @@
1C7364808E72BFA7575E75E1 /* master */, 1C7364808E72BFA7575E75E1 /* master */,
1C7363B608460DED4F522D1C /* photo */, 1C7363B608460DED4F522D1C /* photo */,
1C736E3BE8EC464D6F5DC8FA /* scratch.txt */, 1C736E3BE8EC464D6F5DC8FA /* scratch.txt */,
1C736F3946A38499113D351A /* video */,
); );
path = kplayer; path = kplayer;
sourceTree = "<group>"; sourceTree = "<group>";
@ -299,6 +313,7 @@
CreatedOnToolsVersion = 6.3.1; CreatedOnToolsVersion = 6.3.1;
DevelopmentTeam = G9J99WBBN9; DevelopmentTeam = G9J99WBBN9;
LastSwiftMigration = 0820; LastSwiftMigration = 0820;
ProvisioningStyle = Automatic;
}; };
C98AF5E81B124D6A00D196CC = { C98AF5E81B124D6A00D196CC = {
CreatedOnToolsVersion = 6.3.1; CreatedOnToolsVersion = 6.3.1;
@ -376,7 +391,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
9901417B0A169BA87853DAAE /* [CP] Copy Pods Resources */ = { 9901417B0A169BA87853DAAE /* [CP] Copy Pods Resources */ = {
@ -422,6 +437,8 @@
1C73675C34BE0990D44570BE /* ItemModel.swift in Sources */, 1C73675C34BE0990D44570BE /* ItemModel.swift in Sources */,
1C73691A9C7174E0C6B57267 /* stringutil.swift in Sources */, 1C73691A9C7174E0C6B57267 /* stringutil.swift in Sources */,
1C736821D6DF2237A3EABCC1 /* ViewControllerExtensions.swift in Sources */, 1C736821D6DF2237A3EABCC1 /* ViewControllerExtensions.swift in Sources */,
1C7361D2B6E0AE689FAAF4F4 /* AVPlayerController.swift in Sources */,
1C7369763AB6C73472E11B55 /* KBMPlayer.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -556,15 +573,17 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 6D522F61736592330F481B4F /* Pods-kplayer.debug.xcconfig */; baseConfigurationReference = 6D522F61736592330F481B4F /* Pods-kplayer.debug.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = kplayer/Info.plist; INFOPLIST_FILE = kplayer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "schmickler.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_BUNDLE_IDENTIFIER = "schmickler.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 3.0; SWIFT_VERSION = 3.0;
}; };
name = Debug; name = Debug;
@ -573,15 +592,17 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = DF1DF76780D9CDC55209D1CE /* Pods-kplayer.release.xcconfig */; baseConfigurationReference = DF1DF76780D9CDC55209D1CE /* Pods-kplayer.release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = kplayer/Info.plist; INFOPLIST_FILE = kplayer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "schmickler.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_BUNDLE_IDENTIFIER = "schmickler.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 3.0; SWIFT_VERSION = 3.0;
}; };
name = Release; name = Release;

65
kplayer/Base.lproj/Main.storyboard

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="15G1108" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="H1p-Uh-vWS">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12118" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="H1p-Uh-vWS">
<device id="ipad9_7" orientation="portrait"> <device id="ipad9_7" orientation="portrait">
<adaptation id="fullscreen"/> <adaptation id="fullscreen"/>
</device> </device>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<scenes> <scenes>
@ -14,6 +14,7 @@
<objects> <objects>
<navigationController title="Master" id="RMx-3f-FxP" sceneMemberID="viewController"> <navigationController title="Master" id="RMx-3f-FxP" sceneMemberID="viewController">
<navigationBar key="navigationBar" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="Pmd-2v-anx"> <navigationBar key="navigationBar" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="Pmd-2v-anx">
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</navigationBar> </navigationBar>
<connections> <connections>
@ -56,69 +57,12 @@
<navigationItem key="navigationItem" title="Detail" id="mOI-FS-AaM"/> <navigationItem key="navigationItem" title="Detail" id="mOI-FS-AaM"/>
<connections> <connections>
<outlet property="detailDescriptionLabel" destination="0XM-y9-sOw" id="deQ-Na-JPF"/> <outlet property="detailDescriptionLabel" destination="0XM-y9-sOw" id="deQ-Na-JPF"/>
<segue destination="H2f-hD-mj0" kind="presentation" identifier="showVideo" id="In3-xv-Uwk"/>
</connections> </connections>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="FJe-Yq-33r" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="FJe-Yq-33r" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="709" y="129"/> <point key="canvasLocation" x="709" y="129"/>
</scene> </scene>
<!--Video Player Controller-->
<scene sceneID="6y1-jK-8xM">
<objects>
<viewController id="yqJ-Uz-RRd" customClass="VideoPlayerController" customModule="kplayer" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="t7F-Sd-USd"/>
<viewControllerLayoutGuide type="bottom" id="xB2-3N-aYI"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Hzn-H1-qwy">
<rect key="frame" x="0.0" y="64" width="768" height="960"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<extendedEdge key="edgesForExtendedLayout" top="YES"/>
<navigationItem key="navigationItem" id="gsi-1J-w6z">
<nil key="title"/>
<barButtonItem key="backBarButtonItem" title="back" id="mQc-4U-xZS"/>
<barButtonItem key="leftBarButtonItem" style="plain" id="cd5-8s-DNN">
<button key="customView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="TxA-bq-Yuj">
<rect key="frame" x="20" y="7" width="133" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="zurück">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="back:" destination="yqJ-Uz-RRd" eventType="touchUpInside" id="a9M-Xh-Oid"/>
</connections>
</button>
</barButtonItem>
<connections>
<outlet property="backBarButtonItem" destination="cd5-8s-DNN" id="DKb-D2-VLe"/>
</connections>
</navigationItem>
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" barStyle="black" translucent="NO" prompted="NO"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Wef-7T-g7k" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="709" y="877"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="thV-ok-QsE">
<objects>
<navigationController id="H2f-hD-mj0" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="u2K-vF-nU5">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="yqJ-Uz-RRd" kind="relationship" relationship="rootViewController" id="pGG-bu-FAP"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="yjJ-EY-Ybv" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-65" y="877"/>
</scene>
<!--Split View Controller--> <!--Split View Controller-->
<scene sceneID="Nki-YV-4Qg"> <scene sceneID="Nki-YV-4Qg">
<objects> <objects>
@ -181,6 +125,7 @@
<objects> <objects>
<navigationController id="vC3-pB-5Vb" sceneMemberID="viewController"> <navigationController id="vC3-pB-5Vb" sceneMemberID="viewController">
<navigationBar key="navigationBar" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="DjV-YW-jjY"> <navigationBar key="navigationBar" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="DjV-YW-jjY">
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</navigationBar> </navigationBar>
<connections> <connections>

2
kplayer/core/NetworkManager.swift

@ -12,6 +12,8 @@ class NetworkManager {
let baseurl = "http://linkstation.local/tomcat/media" let baseurl = "http://linkstation.local/tomcat/media"
var authenticated = false
lazy var operationQueue: OperationQueue = { lazy var operationQueue: OperationQueue = {
var queue = OperationQueue() var queue = OperationQueue()
queue.name = "Backup queue" queue.name = "Backup queue"

449
kplayer/detail/AVPlayerController.swift

@ -0,0 +1,449 @@
//
// Created by Marco Schmickler on 26.05.15.
// Copyright (c) 2015 Marco Schmickler. All rights reserved.
//
import Foundation
import UIKit
import Haneke
import BMPlayer
import AVFoundation
protocol ItemController {
func setCurrentItem(item: MediaItem)
func setCompletionHandler(handler: @escaping ((Void) -> Void))
}
class AVPlayerController: UIViewController, ItemController {
var player = KBMPlayer()
var currentItem: MediaItem?
var completionHandler: ((Void) -> Void)?
var buttons = Dictionary<UIButton, MediaItem>()
var barbutton: UIBarButtonItem?
var speedButton: UIBarButtonItem?
var zoomButton: UIBarButtonItem?
var aspectButton: UIBarButtonItem?
var playButton: UIBarButtonItem?
var backButton: UIBarButtonItem?
var reviewButton: UIBarButtonItem?
let speedOptions = [ 0.25, 0.5, 0.75, 1.0, 2.0 ]
var speedOption = 3
var aspect = 1
let zoomOptions = [ 1, 1.25, 1.5, 2.0 ]
var zoomOption = 1
var thumbnailTime: TimeInterval = 0.0
var edit = true
var allowEdit = true
var index = 0
override func viewDidLoad() {
super.viewDidLoad()
barbutton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(AVPlayerController.captureThumbnail));
navigationItem.rightBarButtonItems = [barbutton!]
backButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(AVPlayerController.back(_:)))
speedButton = UIBarButtonItem(title:"1.0", style:UIBarButtonItemStyle.plain, target: self, action: #selector(AVPlayerController.speed(_:)))
zoomButton = UIBarButtonItem(title:"1.0", style:UIBarButtonItemStyle.plain, target: self, action: #selector(AVPlayerController.zoom(_:)))
aspectButton = UIBarButtonItem(title:"1", style:UIBarButtonItemStyle.plain, target: self, action: #selector(AVPlayerController.aspect(_:)))
playButton = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(AVPlayerController.startstop(_:)))
reviewButton = UIBarButtonItem(title:"Edit ", style:UIBarButtonItemStyle.plain, target: self, action: #selector(AVPlayerController.doEdit(_:)))
navigationItem.leftBarButtonItems = [backButton!, speedButton!, playButton!, zoomButton!, aspectButton!, reviewButton!]
view.addSubview(player)
player.snp.makeConstraints { (make) in
make.top.equalTo(self.view).offset(100)
make.left.right.equalTo(self.view)
// Note here, the aspect ratio 16:9 priority is lower than 1000 on the line, because the 4S iPhone aspect ratio is not 16:9
make.height.equalTo(player.snp.width).multipliedBy(9.0/16.0).priority(750)
}
// Back button event
player.backBlock = { (b) in
let _ = self.navigationController?.popViewController(animated: true)
}
if let c = currentItem, let url = c.playerURL {
print(url)
play(url as URL)
update()
}
}
func setCurrentItem(item: MediaItem) {
currentItem = item
}
func setCompletionHandler(handler: @escaping ((Void) -> Void)) {
completionHandler = handler
}
func doEdit(_ sender: AnyObject) {
if (!allowEdit) {
return
}
if (edit) {
edit = false
reviewButton!.tintColor = UIColor.blue
}
else {
edit = true
reviewButton!.tintColor = UIColor.yellow
}
}
func startstop(_ sender: AnyObject) {
if player.isPlaying {
player.pause()
}
else {
player.play()
}
// if moviePlayer!.playbackState == MPMoviePlaybackState.playing {
// moviePlayer!.pause()
// }
// else {
// moviePlayer!.play()
//
// Timer.scheduledTimer(timeInterval: 0.5,
// target: self,
// selector: #selector(resumePlay),
// userInfo: nil,
// repeats: false)
// }
print("play")
}
func zoom(_ sender: AnyObject) {
zoomOption += 1
if zoomOption >= zoomOptions.count {
zoomOption = 0
}
let zoom = Float(zoomOptions[zoomOption])
player.playerLayer!.layer.transform = CATransform3DMakeScale(CGFloat(zoom), CGFloat(zoom), 1.0)
player.zoom = zoom
zoomButton!.title = "\(zoom)"
print("zoom \(zoom)")
}
func aspect(_ sender: AnyObject) {
aspect += 1
if aspect > 3 {
aspect = 1
}
switch aspect {
case 1:
player.aspectx = 1.0
player.aspecty = 1.0
case 2:
player.aspectx = 0.85
player.aspecty = 1.0
case 3:
player.aspectx = 1.0
player.aspecty = 0.85
default:
print("aspect")
}
player.verticalMoved(0)
aspectButton!.title = "\(aspect)"
}
func speed(_ sender: AnyObject) {
speedOption += 1
if speedOption >= speedOptions.count {
speedOption = 0
}
let speed = Float(speedOptions[speedOption])
player.playerLayer!.player!.rate = speed
speedButton!.title = "\(speed)"
print("speed \(speed)")
}
@IBAction func back(_ sender: AnyObject) {
player.playerLayer?.pause()
player.playerLayer?.prepareToDeinit()
completionHandler!()
}
func play(_ url: URL) {
let asset = BMPlayerResource(url: url)
player.setVideo(resource: asset)
player.playerLayer!.player!.automaticallyWaitsToMinimizeStalling = false
if let item = player.playerLayer?.playerItem {
item.canUseNetworkResourcesForLiveStreamingWhilePaused = true
item.preferredForwardBufferDuration = 1
}
}
func playerItemDidReachEnd(_ note: Notification) {
print("finish")
// Timer.scheduledTimer(timeInterval: 0.6, target: self, selector: #selector(update), userInfo: nil, repeats: false)
}
func addItemButton(_ newItem: MediaItem) {
let frame = CGRect(x: 0, y: 0, width: 66.0, height: 44.0);
let button = UIButton(frame: frame)
button.showsTouchWhenHighlighted = true
button.addTarget(self, action: #selector(thumbnailClicked(_:)), for: .touchDown)
if newItem.image != nil {
let icon = newItem.image!.scaleToSize(66.0, height: 44.0)
button.setBackgroundImage(icon, for: UIControlState());
} else {
if newItem.thumbUrl != nil {
let URL = Foundation.URL(string: newItem.thumbUrlAbsolute)!
Shared.imageCache.fetch(URL: URL).onSuccess {
i in
let icon = i.scaleToSize(66.0, height: 44.0)
button.setBackgroundImage(icon, for: UIControlState.normal);
}
}
}
let barbutton = UIBarButtonItem(customView: button);
if navigationItem.rightBarButtonItems == nil {
navigationItem.rightBarButtonItems = []
}
navigationItem.rightBarButtonItems!.append(barbutton)
buttons[button] = newItem
}
func thumbnailClicked(_ source: UIButton) {
player.seek(buttons[source]!.time!)
// moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption])
// print("goto \(buttons[source]!.time!) is \(moviePlayer!.currentPlaybackTime)")
}
func update() {
reviewButton!.title = currentItem!.name
if currentItem!.type == ItemType.SNAPSHOT {
player.seek(currentItem!.time!)
currentItem = currentItem!.parent
} else {
if !currentItem!.children.isEmpty {
player.seek(currentItem!.children[0].time!)
}
else {
let duration = player.playerLayer!.playerItem!.duration.seconds
print(duration)
player.seek(duration / 2.0)
}
}
navigationItem.rightBarButtonItems = [barbutton!]
for c in currentItem!.children {
addItemButton(c)
}
player.play()
}
func enteredFullscreen() {
// let mp = UIApplication.shared.keyWindow;
// if let moviePlayerContainer = mp!.recursiveSearchForViewWithName("MPVideoContainerView") {
// if (moviePlayerContainer.gestureRecognizers != nil) {
// return;
// }
// installGestures(moviePlayerContainer)
// }
}
func exitedFullscreen() {
// moviePlayer!.view.removeFromSuperview();
// moviePlayer = nil;
// NotificationCenter.default.removeObserver(self);
}
func installGestures(_ moviePlayer: UIView) {
let twoFingersTwoTapsGesture = UITapGestureRecognizer(target: self, action: #selector(captureThumbnail))
twoFingersTwoTapsGesture.numberOfTapsRequired = 2
twoFingersTwoTapsGesture.numberOfTouchesRequired = 2
moviePlayer.addGestureRecognizer(twoFingersTwoTapsGesture)
let sR = UISwipeGestureRecognizer(target: self, action: #selector(swipeRight))
sR.direction = UISwipeGestureRecognizerDirection.right
sR.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sR)
let sL = UISwipeGestureRecognizer(target: self, action: #selector(swipeLeft))
sL.direction = UISwipeGestureRecognizerDirection.left
sL.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sL)
let sR2 = UISwipeGestureRecognizer(target: self, action: #selector(swipeDown))
sR2.direction = UISwipeGestureRecognizerDirection.down
sR2.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sR2)
let sR3 = UISwipeGestureRecognizer(target: self, action: #selector(swipeUp))
sR3.direction = UISwipeGestureRecognizerDirection.up
sR3.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sR3)
}
func swipeUp() {
print("u")
print("Type: \(currentItem!.type) Count: \(currentItem!.children.count) Index: \(index) Current: \(currentItem!.index)")
if !edit && (currentItem!.children.isEmpty || !(index < currentItem!.children.count - 1)) {
print ("switch")
var newIndex = currentItem!.index + 1
if currentItem!.parent!.children.count <= newIndex {
newIndex = 0
}
currentItem = currentItem!.parent!.children[newIndex]
print("'Switched Type: \(currentItem!.type) Count: \(currentItem!.children.count) Index: \(index) Current: \(currentItem!.index)")
index = 0
// player.playWithURL(currentItem!.playerURL)
Timer.scheduledTimer(timeInterval: 1.2, target: self, selector: #selector(update), userInfo: nil, repeats: false)
return
}
if !(currentItem!.children.isEmpty) {
print ("switch internal")
if index < currentItem!.children.count - 1 {
index+=1;
} else {
index = 0;
}
let child = currentItem!.children[index]
// player.currentPlaybackTime = child.time!
// player.currentPlaybackRate = Float(speedOptions[speedOption])
}
}
func swipeRight() {
// print("r")
// player.currentPlaybackRate = Float(0.0)
// player.currentPlaybackTime = player.currentPlaybackTime - 30.0
// Timer.scheduledTimer(timeInterval: 0.9,
// target: self,
// selector: #selector(resumePlay),
// userInfo: nil,
// repeats: false)
}
func swipeDown() {
print("d")
if !edit {
var newIndex = currentItem!.index - 1
if newIndex < 0 {
newIndex = 0
}
currentItem = currentItem!.parent!.children[newIndex]
index = 0;
// player.contentURL = currentItem!.playerURL
player.play()
Timer.scheduledTimer(timeInterval: 1.2, target: self, selector: #selector(update), userInfo: nil, repeats: false)
return
}
// player.currentPlaybackTime = player.currentPlaybackTime + 10.0
Timer.scheduledTimer(timeInterval: 0.9,
target: self,
selector: #selector(resumePlay),
userInfo: nil,
repeats: false)
}
func swipeLeft() {
print("l")
// player.currentPlaybackRate = Float(0.0)
// player.currentPlaybackTime = player.currentPlaybackTime + 30.0
Timer.scheduledTimer(timeInterval: 0.9,
target: self,
selector: #selector(resumePlay),
userInfo: nil,
repeats: false)
}
@objc func resumePlay() {
// player.currentPlaybackRate = Float(speedOptions[speedOption])
print("resumePlay")
}
func captureThumbnail() {
if edit {
let asset = player.playerLayer!.playerItem!.asset
do {
let imgGenerator = AVAssetImageGenerator(asset: asset)
imgGenerator.appliesPreferredTrackTransform = true
let time = player.playerLayer!.playerItem!.currentTime()
let cgImage = try imgGenerator.copyCGImage(at: time, actualTime: nil)
let thumbnail = UIImage(cgImage: cgImage)
showThumbnail(thumbnail: thumbnail, time: time)
} catch let error {
print("*** Error generating thumbnail: \(error.localizedDescription)")
}
// thumbnailTime = player.currentPlaybackTime
print("tap \(thumbnailTime)")
// moviePlayer!.requestThumbnailImages(atTimes: [thumbnailTime],
// timeOption: MPMovieTimeOption.exact);
}
else {
NetworkManager.sharedInstance.favItem(currentItem!)
}
}
func showThumbnail(thumbnail: UIImage, time: CMTime) {
let newItem = MediaItem(name: currentItem!.name, path: currentItem!.path, root: currentItem!.root, type: ItemType.SNAPSHOT)
newItem.image = thumbnail
newItem.time = time.seconds
newItem.parent = currentItem!
currentItem!.children.append(newItem)
print(newItem.time)
addItemButton(newItem)
}
}

82
kplayer/detail/DetailViewController.swift

@ -16,6 +16,8 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout
var showFavoritesOnly = false var showFavoritesOnly = false
var collectionView: UICollectionView! var collectionView: UICollectionView!
var videoplayer = false
var currentItem: MediaItem? var currentItem: MediaItem?
var defaultItemSize = CGSize(width: (15 * 16) - 6, height: 15 * 9) var defaultItemSize = CGSize(width: (15 * 16) - 6, height: 15 * 9)
@ -72,12 +74,17 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout
let overviewButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(overview)); let overviewButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(overview));
let favButton = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: self, action: #selector(favorites)); let favButton = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: self, action: #selector(favorites));
navigationItem.rightBarButtonItems = [favButton, overviewButton]
let vidButton = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(vplayer));
navigationItem.rightBarButtonItems = [vidButton, favButton, overviewButton]
if detailItem != nil { if detailItem != nil {
print("Details \(detailItem!.children)") print("Details \(detailItem!.children)")
} }
} }
func vplayer() {
videoplayer = !videoplayer
}
func favorites() { func favorites() {
showFavoritesOnly = !showFavoritesOnly showFavoritesOnly = !showFavoritesOnly
collectionView.reloadData() collectionView.reloadData()
@ -266,7 +273,7 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout
} }
if items.type == ItemType.VIDEO || items.type == ItemType.SNAPSHOT { if items.type == ItemType.VIDEO || items.type == ItemType.SNAPSHOT {
performSegue(withIdentifier: "showVideo", sender: self)
showVideo()
} }
else { else {
let len = items.root.characters.count let len = items.root.characters.count
@ -313,49 +320,56 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout
} }
} }
} }
let pc = MediaPhotoController()
pc.items = im
pc.completionHandler = {
self.dismiss(animated: true, completion: nil);
}
let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack.
self.present(navController, animated: false, completion: nil)
self.showPhotos(im)
} }
} }
} }
} }
} }
func showPhotos(_ im: [MediaItem]) {
let pc = MediaPhotoController()
// MARK: - Segues
pc.items = im
pc.completionHandler = {
self.dismiss(animated: true, completion: nil);
}
let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showVideo" {
let nc = segue.destination as! UINavigationController
let controller = nc.topViewController as! VideoPlayerController
controller.currentItem = self.currentItem
// controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
nc.navigationBar.barTintColor = UIColor.black
self.present(navController, animated: false, completion: nil)
}
controller.completionHandler = {
() in
self.collectionView.reloadData()
self.collectionView.collectionViewLayout.invalidateLayout()
func showVideo() {
// performSegue(withIdentifier: "showVideo", sender: self)
var pc: ItemController?
if let ci = self.currentItem {
if ci.type == ItemType.SNAPSHOT {
self.currentItem = ci.parent
}
}
if let ci = self.currentItem {
NetworkManager.sharedInstance.saveItem(ci)
if videoplayer {
pc = AVPlayerController()
}
else {
pc = VideoPlayerController()
}
pc!.setCurrentItem(item: self.currentItem!)
pc!.setCompletionHandler(handler: {
self.collectionView.reloadData()
self.collectionView.collectionViewLayout.invalidateLayout()
if let ci = self.currentItem {
if ci.type == ItemType.SNAPSHOT {
self.currentItem = ci.parent
} }
self.dismiss(animated: true, completion: nil);
} }
}
if let ci = self.currentItem {
NetworkManager.sharedInstance.saveItem(ci)
}
self.dismiss(animated: true, completion: nil);
})
let navController = UINavigationController(rootViewController: (pc! as! UIViewController))
navController.navigationBar.barTintColor = UIColor.black
(pc! as! UIViewController).navigationItem.leftItemsSupplementBackButton = true
self.present(navController, animated: false, completion: nil)
} }
} }

70
kplayer/detail/VideoPlayerController.swift

@ -9,7 +9,7 @@ import MediaPlayer
import ALMoviePlayerController import ALMoviePlayerController
import Haneke import Haneke
class VideoPlayerController: UIViewController {
class VideoPlayerController: UIViewController, ItemController {
var moviePlayer: ALMoviePlayerController? var moviePlayer: ALMoviePlayerController?
var currentItem: MediaItem? var currentItem: MediaItem?
@ -23,8 +23,8 @@ class VideoPlayerController: UIViewController {
var backButton: UIBarButtonItem? var backButton: UIBarButtonItem?
var reviewButton: UIBarButtonItem? var reviewButton: UIBarButtonItem?
let speedOptions = [ 0.25, 0.5, 1.0, 2.0 ]
var speedOption = 2
let speedOptions = [ 0.25, 0.5, 0.75, 1.0, 2.0 ]
var speedOption = 3
var thumbnailTime: TimeInterval = 0.0 var thumbnailTime: TimeInterval = 0.0
@ -32,6 +32,10 @@ class VideoPlayerController: UIViewController {
var allowEdit = true var allowEdit = true
var index = 0 var index = 0
func setCompletionHandler(handler: @escaping ((Void) -> Void)) {
completionHandler = handler
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
@ -51,6 +55,10 @@ class VideoPlayerController: UIViewController {
} }
} }
func setCurrentItem(item: MediaItem) {
currentItem = item
}
func doEdit(_ sender: AnyObject) { func doEdit(_ sender: AnyObject) {
if (!allowEdit) { if (!allowEdit) {
return return
@ -72,14 +80,19 @@ class VideoPlayerController: UIViewController {
} }
else { else {
moviePlayer!.play() moviePlayer!.play()
moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption])
Timer.scheduledTimer(timeInterval: 0.5,
target: self,
selector: #selector(resumePlay),
userInfo: nil,
repeats: false)
} }
print("play") print("play")
} }
func speed(_ sender: AnyObject) { func speed(_ sender: AnyObject) {
speedOption += 1 speedOption += 1
if speedOption > 3 {
if speedOption >= speedOptions.count {
speedOption = 0 speedOption = 0
} }
@ -90,9 +103,6 @@ print("play")
} }
@IBAction func back(_ sender: AnyObject) { @IBAction func back(_ sender: AnyObject) {
if let player = self.moviePlayer {
player.stop()
}
completionHandler!() completionHandler!()
} }
@ -108,6 +118,7 @@ print("play")
NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.exitedFullscreen), name: NSNotification.Name.MPMoviePlayerDidExitFullscreen, object: nil); NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.exitedFullscreen), name: NSNotification.Name.MPMoviePlayerDidExitFullscreen, object: nil);
NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.enteredFullscreen), name: NSNotification.Name.MPMoviePlayerDidEnterFullscreen, object: nil); NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.enteredFullscreen), name: NSNotification.Name.MPMoviePlayerDidEnterFullscreen, object: nil);
NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.showThumbnail(_:)), name: NSNotification.Name.MPMoviePlayerThumbnailImageRequestDidFinish, object: nil); NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.showThumbnail(_:)), name: NSNotification.Name.MPMoviePlayerThumbnailImageRequestDidFinish, object: nil);
NotificationCenter.default.addObserver(self, selector: #selector(VideoPlayerController.playerItemDidReachEnd(_:)), name: NSNotification.Name.MPMoviePlayerLoadStateDidChange, object: nil);
player.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height) player.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
player.view.sizeToFit() player.view.sizeToFit()
@ -123,6 +134,11 @@ print("play")
} }
} }
func playerItemDidReachEnd(_ note: Notification) {
print("finish")
// Timer.scheduledTimer(timeInterval: 0.6, target: self, selector: #selector(update), userInfo: nil, repeats: false)
}
func showThumbnail(_ note: Notification) { func showThumbnail(_ note: Notification) {
let userInfo = note.userInfo! as NSDictionary let userInfo = note.userInfo! as NSDictionary
let thumbnail = userInfo.object(forKey: MPMoviePlayerThumbnailImageKey) as! UIImage let thumbnail = userInfo.object(forKey: MPMoviePlayerThumbnailImageKey) as! UIImage
@ -183,11 +199,11 @@ print("play")
func update() { func update() {
if let player = self.moviePlayer { if let player = self.moviePlayer {
if !(player.duration > 0.0) {
print("again")
Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(update), userInfo: nil, repeats: false)
return
}
// if !(player.duration > 0.0) {
// print("again")
// Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(update), userInfo: nil, repeats: false)
// return
// }
reviewButton!.title = currentItem!.name reviewButton!.title = currentItem!.name
@ -301,8 +317,14 @@ print("play")
func swipeRight() { func swipeRight() {
print("r") print("r")
if let player = self.moviePlayer { if let player = self.moviePlayer {
moviePlayer!.currentPlaybackRate = Float(0.0)
player.currentPlaybackTime = player.currentPlaybackTime - 30.0 player.currentPlaybackTime = player.currentPlaybackTime - 30.0
moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption])
Timer.scheduledTimer(timeInterval: 0.9,
target: self,
selector: #selector(resumePlay),
userInfo: nil,
repeats: false)
} }
} }
@ -327,18 +349,34 @@ print("play")
return return
} }
player.currentPlaybackTime = player.currentPlaybackTime + 10.0 player.currentPlaybackTime = player.currentPlaybackTime + 10.0
moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption])
Timer.scheduledTimer(timeInterval: 0.9,
target: self,
selector: #selector(resumePlay),
userInfo: nil,
repeats: false)
} }
} }
func swipeLeft() { func swipeLeft() {
print("l") print("l")
if let player = self.moviePlayer { if let player = self.moviePlayer {
moviePlayer!.currentPlaybackRate = Float(0.0)
player.currentPlaybackTime = player.currentPlaybackTime + 30.0 player.currentPlaybackTime = player.currentPlaybackTime + 30.0
moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption])
Timer.scheduledTimer(timeInterval: 0.9,
target: self,
selector: #selector(resumePlay),
userInfo: nil,
repeats: false)
} }
} }
@objc func resumePlay() {
moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption])
print("resumePlay")
}
func twoFingersTwoTaps() { func twoFingersTwoTaps() {
if edit { if edit {
thumbnailTime = moviePlayer!.currentPlaybackTime thumbnailTime = moviePlayer!.currentPlaybackTime

50
kplayer/master/MasterViewController.swift

@ -8,11 +8,14 @@
import UIKit import UIKit
import CoreData import CoreData
import LocalAuthentication
class MasterViewController: UITableViewController, UISearchResultsUpdating { class MasterViewController: UITableViewController, UISearchResultsUpdating {
let searchController = UISearchController(searchResultsController: nil) let searchController = UISearchController(searchResultsController: nil)
let model = ItemModel() let model = ItemModel()
var authenticated = false
override func awakeFromNib() { override func awakeFromNib() {
super.awakeFromNib() super.awakeFromNib()
if UIDevice.current.userInterfaceIdiom == .pad { if UIDevice.current.userInterfaceIdiom == .pad {
@ -40,10 +43,12 @@ class MasterViewController: UITableViewController, UISearchResultsUpdating {
if str.hasSuffix("*") { if str.hasSuffix("*") {
let txt = str[str.startIndex ..< str.characters.index(str.endIndex, offsetBy: -1)] let txt = str[str.startIndex ..< str.characters.index(str.endIndex, offsetBy: -1)]
let neu = MediaItem(name: txt, path: model.items[0].parent!.path + "*" + txt, root: model.items[0].parent!.root, type: ItemType.DETAILS)
model.items.append(neu)
neu.parent = model.items[0].parent
self.tableView.reloadData()
if let p = model.items[0].parent {
let neu = MediaItem(name: txt, path: p.path + "*" + txt, root: p.root, type: ItemType.DETAILS)
model.items.append(neu)
neu.parent = p
self.tableView.reloadData()
}
} }
} }
@ -63,8 +68,44 @@ class MasterViewController: UITableViewController, UISearchResultsUpdating {
} }
} }
func doAuthenticate() {
let authenticationContext = LAContext()
var error : NSError?
guard authenticationContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
self.showAlert(title: "Error", message: "This device does not have a TouchID sensor.")
return;
}
authenticationContext.evaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics,
localizedReason: "Only awesome people are allowed",
reply: { [unowned self] (success, error) -> Void in
NetworkManager.sharedInstance.authenticated = success
})
}
func showAlert(title:String, message:String ) {
let alertVC = UIAlertController(title: title, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alertVC.addAction(okAction)
DispatchQueue.main.async() { () -> Void in
self.present(alertVC, animated: true, completion: nil)
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("\(indexPath.row)") print("\(indexPath.row)")
if (!NetworkManager.sharedInstance.authenticated) {
doAuthenticate()
return
}
let selectedItem = model.items[indexPath.row] let selectedItem = model.items[indexPath.row]
if selectedItem.type == ItemType.DETAILS { if selectedItem.type == ItemType.DETAILS {
@ -73,7 +114,6 @@ class MasterViewController: UITableViewController, UISearchResultsUpdating {
// selectLoadedItem(selectedItem) // selectLoadedItem(selectedItem)
} }
if (selectedItem.isFolder()) { if (selectedItem.isFolder()) {
print(selectedItem.path) print(selectedItem.path)

59
kplayer/video/KBMPlayer.swift

@ -0,0 +1,59 @@
//
// BMPlayer.swift
// Pods
//
// Created by BrikerMan on 16/4/28.
//
//
import UIKit
import SnapKit
import MediaPlayer
import BMPlayer
/**
internal enum to check the pan direction
- horizontal: horizontal
- vertical: vertical
*/
enum BMPanDirection: Int {
case horizontal = 0
case vertical = 1
}
open class KBMPlayer: BMPlayer {
open var zoom = Float(1.0)
open var aspectx = Float(1.0)
open var aspecty = Float(1.0)
var xpos = 0.0
var ypos = 0.0
open override func horizontalMoved(_ value: CGFloat) {
if zoom == 1.0 {
super.horizontalMoved(value)
xpos = 0.0
ypos = 0.0
}
else {
xpos += (Double(value) / 50.0)
}
let t = CATransform3DMakeTranslation(CGFloat(xpos), CGFloat(ypos), 0.0)
playerLayer!.layer.transform = CATransform3DScale(t, CGFloat(zoom * aspectx), CGFloat(zoom * aspecty), 1.0)
}
open override func verticalMoved(_ value: CGFloat) {
if zoom == 1.0 {
// super.verticalMoved(value)
xpos = 0.0
ypos = 0.0
}
else {
ypos += (Double(value) / 50.0)
}
let t = CATransform3DMakeTranslation(CGFloat(xpos), CGFloat(ypos), 0.0)
playerLayer!.layer.transform = CATransform3DScale(t, CGFloat(zoom * aspectx), CGFloat(zoom * aspecty), 1.0)
}
}
Loading…
Cancel
Save