add ReplayKit Live Template #81
This commit is contained in:
parent
db7a9d2195
commit
ad9faa7d48
|
@ -18,8 +18,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
return controller
|
||||
}()
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: Any]?) -> Bool {
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
|
||||
XCGLogger.defaultInstance().outputLogLevel = .info
|
||||
XCGLogger.defaultInstance().xcodeColorsEnabled = true
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string></string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string></string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
|
|
|
@ -98,7 +98,7 @@ final class LiveViewController: UIViewController {
|
|||
UIBarButtonItem(title: "Camera", style: .plain, target: self, action: #selector(LiveViewController.rotateCamera(_:)))
|
||||
]
|
||||
|
||||
rtmpStream = RTMPStream(rtmpConnection: rtmpConnection)
|
||||
rtmpStream = RTMPStream(connection: rtmpConnection)
|
||||
rtmpStream.syncOrientation = true
|
||||
|
||||
rtmpStream.attach(audio: AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio))
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?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>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Screencast</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>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.broadcast-services</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).SampleHandler</string>
|
||||
<key>RPBroadcastProcessMode</key>
|
||||
<string>RPBroadcastProcessModeSampleBuffer</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,6 @@
|
|||
import ReplayKit
|
||||
import lf
|
||||
|
||||
@available(iOS 10.0, *)
|
||||
class SampleHandler: RTMPSampleHandler {
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11198.2" systemVersion="15G1004" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="ObA-dk-sSI">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Broadcast View Controller-->
|
||||
<scene sceneID="7MM-of-jgj">
|
||||
<objects>
|
||||
<viewController id="ObA-dk-sSI" customClass="BroadcastViewController" customModule="ScreencastUI" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="qkL-Od-lgU"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="n38-gi-rB5"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="zMn-AG-sqS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="rtmpt://192.168.179.4:1935/live" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="GKU-M2-aRK">
|
||||
<frame key="frameInset" minX="16" minY="60" width="222" height="30"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<nil key="textColor"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
</textField>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4nz-OC-sf0">
|
||||
<frame key="frameInset" minX="252" minY="59" width="34" height="30"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<state key="normal" title="Start"/>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<size key="freeformSize" width="320" height="150"/>
|
||||
<connections>
|
||||
<outlet property="endpointURLField" destination="GKU-M2-aRK" id="mGY-Jv-ucw"/>
|
||||
<outlet property="startButton" destination="4nz-OC-sf0" id="vuY-tv-8xP"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="X47-rx-isc" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,37 @@
|
|||
import ReplayKit
|
||||
|
||||
class BroadcastViewController: UIViewController {
|
||||
@IBOutlet
|
||||
var startButton:UIButton!
|
||||
|
||||
@IBOutlet
|
||||
var endpointURLField:UITextField!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
startButton.addTarget(self, action: #selector(BroadcastViewController.userDidFinishSetup), for: .touchDown)
|
||||
}
|
||||
|
||||
func userDidFinishSetup() {
|
||||
|
||||
let broadcastURL:URL = URL(string: endpointURLField.text!)!
|
||||
|
||||
let endpointURL:String = endpointURLField.text!
|
||||
let setupInfo: [String: NSCoding & NSObjectProtocol] = [
|
||||
"endpointURL" : endpointURL as NSString
|
||||
]
|
||||
|
||||
let broadcastConfiguration:RPBroadcastConfiguration = RPBroadcastConfiguration()
|
||||
|
||||
self.extensionContext?.completeRequest(
|
||||
withBroadcast: broadcastURL,
|
||||
broadcastConfiguration: broadcastConfiguration,
|
||||
setupInfo: setupInfo
|
||||
)
|
||||
}
|
||||
|
||||
func userDidCancelSetup() {
|
||||
let error = NSError(domain: "com.github.shogo4405.lf", code: -1, userInfo: nil)
|
||||
self.extensionContext?.cancelRequest(withError: error)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?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>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>ScreencastUI</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>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsReplayKitStreaming</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
<string>MainInterface</string>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.broadcast-services</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -11,7 +11,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
|
||||
XCGLogger.defaultInstance().xcodeColorsEnabled = true
|
||||
XCGLogger.defaultInstance().setup(
|
||||
.verbose,
|
||||
.info,
|
||||
showThreadName: true, showLogLevel: true, showFileNames: true, showLineNumbers: true, writeToFile: nil, fileLogLevel: nil)
|
||||
|
||||
let viewController:LiveViewController = LiveViewController()
|
||||
|
|
|
@ -3,7 +3,7 @@ import Cocoa
|
|||
import AVFoundation
|
||||
|
||||
final class LiveViewController: NSViewController {
|
||||
static let defaultURL:String = "rtmp://test:test@192.168.179.4:1935/live"
|
||||
static let defaultURL:String = "rtmpt://test:test@192.168.179.4:1935/live"
|
||||
|
||||
var enabledSharedObject:Bool = false
|
||||
var rtmpConnection:RTMPConnection = RTMPConnection()
|
||||
|
@ -84,7 +84,7 @@ final class LiveViewController: NSViewController {
|
|||
super.viewDidLoad()
|
||||
audioPopUpButton.target = self
|
||||
cameraPopUpButton.target = self
|
||||
rtmpStream = RTMPStream(rtmpConnection: rtmpConnection)
|
||||
rtmpStream = RTMPStream(connection: rtmpConnection)
|
||||
rtmpStream.attach(
|
||||
audio: DeviceUtil.device(withLocalizedName: audioPopUpButton.itemTitles[audioPopUpButton.indexOfSelectedItem], mediaType: AVMediaTypeAudio)
|
||||
)
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
import ReplayKit
|
||||
import Foundation
|
||||
|
||||
@available(iOS 10.0, *)
|
||||
public class RTMPBroadcaster: RTMPConnection {
|
||||
internal var stream:RTMPStream?
|
||||
internal var formatDescriptions:[RPSampleBufferType:CMFormatDescription] = [:]
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
override public func connect(withCommand: String, arguments: Any?...) {
|
||||
addEventListener(type: Event.RTMP_STATUS, selector: #selector(RTMPBroadcaster.on(status:)), observer: self)
|
||||
super.connect(withCommand: withCommand, arguments: arguments)
|
||||
}
|
||||
|
||||
override public func close() {
|
||||
super.close()
|
||||
removeEventListener(type: Event.RTMP_STATUS, selector: #selector(RTMPBroadcaster.on(status:)), observer: self)
|
||||
formatDescriptions.removeAll()
|
||||
}
|
||||
|
||||
internal func process(sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
|
||||
guard let stream:RTMPStream = stream, stream.readyState == .publishing else {
|
||||
return
|
||||
}
|
||||
switch sampleBufferType {
|
||||
case .video:
|
||||
stream.mixer.videoIO.captureOutput(nil, didOutputSampleBuffer: sampleBuffer, from: nil)
|
||||
case .audioApp:
|
||||
stream.mixer.audioIO.captureOutput(nil, didOutputSampleBuffer: sampleBuffer, from: nil)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func on(status:Notification) {
|
||||
let e:Event = Event.from(status)
|
||||
guard let data:ASObject = e.data as? ASObject, let code:String = data["code"] as? String else {
|
||||
return
|
||||
}
|
||||
switch code {
|
||||
case RTMPConnection.Code.connectSuccess.rawValue:
|
||||
stream = RTMPStream(connection: self)
|
||||
stream?.publish(withName: "live")
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 10.0, *)
|
||||
open class RTMPSampleHandler: RPBroadcastSampleHandler {
|
||||
|
||||
public static var broadcaster:RTMPBroadcaster?
|
||||
|
||||
override open func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {
|
||||
logger.info("broadcastStarted:\(setupInfo)")
|
||||
guard let endpointURL:String = setupInfo?["endpointURL"] as? String else {
|
||||
return
|
||||
}
|
||||
RTMPSampleHandler.broadcaster = RTMPBroadcaster()
|
||||
RTMPSampleHandler.broadcaster?.connect(withCommand: endpointURL)
|
||||
}
|
||||
|
||||
override open func broadcastPaused() {
|
||||
logger.info("broadcastPaused")
|
||||
}
|
||||
|
||||
override open func broadcastResumed() {
|
||||
logger.info("broadcastResumed")
|
||||
}
|
||||
|
||||
override open func broadcastFinished() {
|
||||
logger.info("broadcastFinished")
|
||||
RTMPSampleHandler.broadcaster?.close()
|
||||
RTMPSampleHandler.broadcaster = nil
|
||||
}
|
||||
|
||||
override open func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
|
||||
RTMPSampleHandler.broadcaster?.process(sampleBuffer: sampleBuffer, with: sampleBufferType)
|
||||
}
|
||||
}
|
|
@ -4,24 +4,21 @@ import AVFoundation
|
|||
open class LFView: NSView {
|
||||
public static var defaultBackgroundColor:NSColor = NSColor.black
|
||||
|
||||
internal var position:AVCaptureDevicePosition = .front {
|
||||
didSet {
|
||||
/*
|
||||
let when:dispatch_time_t = DispatchTime.now(dispatch_time_t(DISPATCH_TIME_NOW), Int64(0.1 * Double(NSEC_PER_SEC)))
|
||||
dispatch_after(when, DispatchQueue.main) {
|
||||
self.frame = NSRect(x: 0, y: 0, width: self.frame.width - 0.1, height: self.frame.height - 0.1)
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
internal var orientation:AVCaptureVideoOrientation = .portrait
|
||||
|
||||
public var videoGravity:String = AVLayerVideoGravityResizeAspect {
|
||||
didSet {
|
||||
layer?.setValue(videoGravity, forKey: "videoGravity")
|
||||
}
|
||||
}
|
||||
|
||||
internal var position:AVCaptureDevicePosition = .front {
|
||||
didSet {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
self.frame = NSRect(x: 0, y: 0, width: self.frame.width - 0.1, height: self.frame.height - 0.1)
|
||||
}
|
||||
}
|
||||
}
|
||||
internal var orientation:AVCaptureVideoOrientation = .portrait
|
||||
|
||||
private weak var currentStream:NetStream? {
|
||||
didSet {
|
||||
guard let oldValue:NetStream = oldValue else {
|
||||
|
|
|
@ -69,7 +69,7 @@ class TSReader {
|
|||
packetizedElementaryStreams[packet.PID] = PacketizedElementaryStream(bytes: packet.payload)
|
||||
return
|
||||
}
|
||||
packetizedElementaryStreams[packet.PID]?.append(packet.payload)
|
||||
let _:Int? = packetizedElementaryStreams[packet.PID]?.append(packet.payload)
|
||||
}
|
||||
|
||||
internal func close() {
|
||||
|
|
|
@ -21,7 +21,7 @@ final class AudioIOComponent: IOComponent {
|
|||
}
|
||||
}
|
||||
|
||||
fileprivate var _output:AVCaptureAudioDataOutput? = nil
|
||||
private var _output:AVCaptureAudioDataOutput? = nil
|
||||
internal var output:AVCaptureAudioDataOutput! {
|
||||
get {
|
||||
if (_output == nil) {
|
||||
|
|
|
@ -28,7 +28,7 @@ open class Responder: NSObject {
|
|||
flash.net.NetConnection for Swift
|
||||
*/
|
||||
open class RTMPConnection: EventDispatcher {
|
||||
static public let supportedProtocols:[String] = ["rtmp", "rtmps"]
|
||||
static public let supportedProtocols:[String] = ["rtmp", "rtmps", "rtmpt"]
|
||||
static public let defaultPort:Int = 1935
|
||||
static public let defaultFlashVer:String = "FMLE/3.0 (compatible; FMSc/1.0)"
|
||||
static public let defaultChunkSizeS:Int = 1024 * 8
|
||||
|
@ -180,7 +180,7 @@ open class RTMPConnection: EventDispatcher {
|
|||
/// The statistics of outgoing bytes per second.
|
||||
dynamic open fileprivate(set) var currentBytesOutPerSecond:Int32 = 0
|
||||
|
||||
var socket:RTMPSocketCompatible = RTMPSocket()
|
||||
var socket:RTMPSocketCompatible!
|
||||
var streams:[UInt32: RTMPStream] = [:]
|
||||
var bandWidth:UInt32 = 0
|
||||
var streamsmap:[UInt16: UInt32] = [:]
|
||||
|
@ -206,7 +206,6 @@ open class RTMPConnection: EventDispatcher {
|
|||
|
||||
override public init() {
|
||||
super.init()
|
||||
socket.delegate = self
|
||||
addEventListener(type: Event.RTMP_STATUS, selector: #selector(RTMPConnection.rtmpStatusHandler(_:)))
|
||||
}
|
||||
|
||||
|
@ -215,7 +214,7 @@ open class RTMPConnection: EventDispatcher {
|
|||
removeEventListener(type: Event.RTMP_STATUS, selector: #selector(RTMPConnection.rtmpStatusHandler(_:)))
|
||||
}
|
||||
|
||||
open func call(_ commandName:String, responder:Responder?, arguments:Any?...) {
|
||||
open func call(commandName:String, responder:Responder?, arguments:Any?...) {
|
||||
guard connected else {
|
||||
return
|
||||
}
|
||||
|
@ -246,6 +245,8 @@ open class RTMPConnection: EventDispatcher {
|
|||
self.uri = uri
|
||||
self.arguments = arguments
|
||||
timer = Timer(timeInterval: 1.0, target: self, selector: #selector(RTMPConnection.on(timer:)), userInfo: nil, repeats: true)
|
||||
socket = uri.scheme == "rtmpt" ? RTMPTSocket() : RTMPSocket()
|
||||
socket.delegate = self
|
||||
socket.securityLevel = uri.scheme == "rtmps" ? .negotiatedSSL : .none
|
||||
socket.connect(withName: uri.host!, port: (uri as NSURL).port == nil ? RTMPConnection.defaultPort : (uri as NSURL).port!.intValue)
|
||||
}
|
||||
|
@ -278,7 +279,7 @@ open class RTMPConnection: EventDispatcher {
|
|||
stream.readyState = .open
|
||||
}
|
||||
})
|
||||
call("createStream", responder: responder)
|
||||
call(commandName: "createStream", responder: responder)
|
||||
}
|
||||
|
||||
internal func rtmpStatusHandler(_ notification: Notification) {
|
||||
|
|
|
@ -422,7 +422,7 @@ final class RTMPDataMessage: RTMPMessage {
|
|||
super.init(type: objectEncoding == 0x00 ? .amf0Data : .amf3Data)
|
||||
}
|
||||
|
||||
internal init(streamId:UInt32, objectEncoding:UInt8, handlerName:String, arguments:[Any?]) {
|
||||
internal init(streamId:UInt32, objectEncoding:UInt8, handlerName:String, arguments:[Any?] = []) {
|
||||
self.objectEncoding = objectEncoding
|
||||
self.handlerName = handlerName
|
||||
self.arguments = arguments
|
||||
|
@ -430,10 +430,6 @@ final class RTMPDataMessage: RTMPMessage {
|
|||
self.streamId = streamId
|
||||
}
|
||||
|
||||
convenience internal init(streamId:UInt32, objectEncoding:UInt8, handlerName:String) {
|
||||
self.init(streamId: streamId, objectEncoding: objectEncoding, handlerName: handlerName, arguments: [])
|
||||
}
|
||||
|
||||
override func execute(_ connection: RTMPConnection) {
|
||||
guard let stream:RTMPStream = connection.streams[streamId] else {
|
||||
return
|
||||
|
|
|
@ -58,8 +58,8 @@ extension RTMPMuxer: AudioEncoderDelegate {
|
|||
extension RTMPMuxer: VideoEncoderDelegate {
|
||||
// MARK: VideoEncoderDelegate
|
||||
internal func didSetFormatDescription(video formatDescription: CMFormatDescription?) {
|
||||
guard let
|
||||
formatDescription:CMFormatDescription = formatDescription,
|
||||
guard
|
||||
let formatDescription:CMFormatDescription = formatDescription,
|
||||
let avcC:Data = AVCConfigurationRecord.getData(formatDescription) else {
|
||||
return
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ extension RTMPMuxer: VideoEncoderDelegate {
|
|||
data[2..<5] = cto.bigEndian.bytes[1..<4]
|
||||
buffer.append(&data, length: data.count)
|
||||
buffer.append(dataPointer!, length: totalLength)
|
||||
|
||||
delegate?.sampleOutput(self, video: buffer as Data, timestamp: delta)
|
||||
videoTimestamp = dts
|
||||
}
|
||||
|
|
|
@ -255,16 +255,15 @@ open class RTMPStream: NetStream {
|
|||
internal var audioTimestamp:Double = 0
|
||||
internal var videoTimestamp:Double = 0
|
||||
internal fileprivate(set) var audioPlayback:RTMPAudioPlayback = RTMPAudioPlayback()
|
||||
|
||||
fileprivate var muxer:RTMPMuxer = RTMPMuxer()
|
||||
internal fileprivate(set) var muxer:RTMPMuxer = RTMPMuxer()
|
||||
fileprivate var frameCount:UInt8 = 0
|
||||
fileprivate var chunkTypes:[FLVTag.TagType:Bool] = [:]
|
||||
fileprivate var dispatcher:IEventDispatcher!
|
||||
fileprivate var howToPublish:RTMPStream.HowToPublish = .live
|
||||
fileprivate var rtmpConnection:RTMPConnection
|
||||
|
||||
public init(rtmpConnection: RTMPConnection) {
|
||||
self.rtmpConnection = rtmpConnection
|
||||
public init(connection: RTMPConnection) {
|
||||
self.rtmpConnection = connection
|
||||
super.init()
|
||||
self.dispatcher = EventDispatcher(target: self)
|
||||
rtmpConnection.addEventListener(type: Event.RTMP_STATUS, selector: #selector(RTMPStream.rtmpStatusHandler(_:)), observer: self)
|
||||
|
@ -345,7 +344,7 @@ open class RTMPStream: NetStream {
|
|||
}
|
||||
}
|
||||
|
||||
open func seek(_ offset:Double) {
|
||||
open func seek(withOffset:Double) {
|
||||
lockQueue.async {
|
||||
guard self.readyState == .playing else {
|
||||
return
|
||||
|
@ -356,7 +355,7 @@ open class RTMPStream: NetStream {
|
|||
objectEncoding: self.objectEncoding,
|
||||
commandName: "seek",
|
||||
commandObject: nil,
|
||||
arguments: [offset]
|
||||
arguments: [withOffset]
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -519,14 +518,14 @@ extension RTMPStream {
|
|||
guard let name:String = info.resourceName , rtmpConnection.flashVer.contains("FMLE/") else {
|
||||
return
|
||||
}
|
||||
rtmpConnection.call("FCPublish", responder: nil, arguments: name)
|
||||
rtmpConnection.call(commandName: "FCPublish", responder: nil, arguments: name)
|
||||
}
|
||||
|
||||
func FCUnpublish() {
|
||||
guard let name:String = info.resourceName , rtmpConnection.flashVer.contains("FMLE/") else {
|
||||
return
|
||||
}
|
||||
rtmpConnection.call("FCUnpublish", responder: nil, arguments: name)
|
||||
rtmpConnection.call(commandName: "FCUnpublish", responder: nil, arguments: name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Foundation
|
||||
|
||||
final internal class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
||||
internal static let contentType:String = "application/x-fcs"
|
||||
|
||||
internal var timeout:Int64 = 0
|
||||
internal var timestamp:TimeInterval = 0
|
||||
|
@ -41,11 +42,15 @@ final internal class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
}
|
||||
}
|
||||
|
||||
private var events:[Event] = []
|
||||
private var mutex:Mutex = Mutex()
|
||||
private var index:Int64 = 0
|
||||
private var events:[Event] = []
|
||||
private var baseURL:URL!
|
||||
private var session:URLSession!
|
||||
private var c2packet:[UInt8] = []
|
||||
private var isPending:Bool = false
|
||||
private var connectionID:String!
|
||||
private var outputBuffer:[UInt8] = []
|
||||
|
||||
override internal init() {
|
||||
super.init()
|
||||
|
@ -53,14 +58,15 @@ final internal class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
|
||||
internal func connect(withName:String, port:Int) {
|
||||
let config:URLSessionConfiguration = URLSessionConfiguration.default
|
||||
config.httpShouldUsePipelining = true
|
||||
config.httpAdditionalHeaders = [
|
||||
"Content-Type": "application/x-fcs",
|
||||
"Content-Type": RTMPTSocket.contentType,
|
||||
"User-Agent": "Shockwave Flash",
|
||||
]
|
||||
let scheme:String = securityLevel == .none ? "http" : "https"
|
||||
session = URLSession(configuration: config)
|
||||
baseURL = URL(string: "\(scheme)://\(withName):\(port)")!
|
||||
doRequest(pathComonent: "/fcs/ident2", data: Data([0x00]), completionHandler:didIdent2)
|
||||
doRequest("/fcs/ident2", Data([0x00]), didIdent2)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
|
@ -70,30 +76,73 @@ final internal class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
for chunk in chunks {
|
||||
bytes.append(contentsOf: chunk)
|
||||
}
|
||||
doOutput(bytes: bytes)
|
||||
do {
|
||||
try mutex.lock()
|
||||
outputBuffer.append(contentsOf: bytes)
|
||||
if (!isPending) {
|
||||
isPending = true
|
||||
doOutput(bytes: outputBuffer)
|
||||
outputBuffer.removeAll()
|
||||
}
|
||||
mutex.unlock()
|
||||
} catch {
|
||||
logger.warning("")
|
||||
}
|
||||
if (logger.isEnabledForLogLevel(.verbose)) {
|
||||
logger.verbose("\(chunk)")
|
||||
}
|
||||
return bytes.count
|
||||
}
|
||||
|
||||
internal func close(isDisconnected:Bool) {
|
||||
deinitConnection(isDisconnected: isDisconnected)
|
||||
}
|
||||
|
||||
internal func deinitConnection(isDisconnected:Bool) {
|
||||
if (isDisconnected) {
|
||||
let data:ASObject = (readyState == .handshakeDone) ?
|
||||
RTMPConnection.Code.connectClosed.data("") : RTMPConnection.Code.connectFailed.data("")
|
||||
events.append(Event(type: Event.RTMP_STATUS, bubbles: false, data: data))
|
||||
}
|
||||
guard let connectionID:String = connectionID else {
|
||||
return
|
||||
}
|
||||
doRequest("/close/\(connectionID)", Data(), didClose)
|
||||
}
|
||||
|
||||
internal func listen(data:Data?, response:URLResponse?, error:Error?) {
|
||||
private func listen(data:Data?, response:URLResponse?, error:Error?) {
|
||||
if (logger.isEnabledForLogLevel(.verbose)) {
|
||||
logger.verbose("\(data):\(response):\(error)")
|
||||
}
|
||||
|
||||
if let error:Error = error {
|
||||
logger.error("\(error)")
|
||||
return
|
||||
}
|
||||
|
||||
guard let data:Data = data else {
|
||||
do {
|
||||
try mutex.lock()
|
||||
if (outputBuffer.isEmpty) {
|
||||
isPending = false
|
||||
} else {
|
||||
doOutput(bytes: outputBuffer)
|
||||
outputBuffer.removeAll()
|
||||
}
|
||||
mutex.unlock()
|
||||
} catch {
|
||||
logger.warning()
|
||||
}
|
||||
|
||||
guard
|
||||
let response:HTTPURLResponse = response as? HTTPURLResponse,
|
||||
let contentType:String = response.allHeaderFields["Content-Type"] as? String,
|
||||
let data:Data = data, contentType == RTMPTSocket.contentType else {
|
||||
return
|
||||
}
|
||||
|
||||
logger.info("\(data.bytes):\(response):\(error)")
|
||||
|
||||
var idel:UInt8 = 0
|
||||
var buffer:[UInt8] = data.bytes
|
||||
buffer.remove(at: 0)
|
||||
idel = buffer.remove(at: 0)
|
||||
inputBuffer.append(contentsOf: buffer)
|
||||
|
||||
switch readyState {
|
||||
|
@ -105,7 +154,7 @@ final internal class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
.writeBytes(Array(inputBuffer[1...4]))
|
||||
.writeInt32(Int32(Date().timeIntervalSince1970 - timestamp))
|
||||
.writeBytes(Array(inputBuffer[9...RTMPSocket.sigSize]))
|
||||
doOutput(bytes: c2packet.bytes)
|
||||
self.c2packet = c2packet.bytes
|
||||
inputBuffer = Array(inputBuffer[RTMPSocket.sigSize + 1..<inputBuffer.count])
|
||||
readyState = .ackSent
|
||||
fallthrough
|
||||
|
@ -127,16 +176,17 @@ final internal class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
}
|
||||
}
|
||||
|
||||
internal func didIdent2(data:Data?, response:URLResponse?, error:Error?) {
|
||||
logger.info("\(data?.bytes):\(response):\(error)")
|
||||
private func didIdent2(data:Data?, response:URLResponse?, error:Error?) {
|
||||
if let error:Error = error {
|
||||
logger.error("\(error)")
|
||||
}
|
||||
doRequest(pathComonent: "/open/1", data: Data([0x00]), completionHandler: didOpen)
|
||||
doRequest("/open/1", Data([0x00]), didOpen)
|
||||
if (logger.isEnabledForLogLevel(.verbose)) {
|
||||
logger.verbose("\(data?.bytes):\(response)")
|
||||
}
|
||||
}
|
||||
|
||||
internal func didOpen(data:Data?, response:URLResponse?, error:Error?) {
|
||||
logger.info("\(data?.bytes):\(response):\(error)")
|
||||
private func didOpen(data:Data?, response:URLResponse?, error:Error?) {
|
||||
if let error:Error = error {
|
||||
logger.error("\(error)")
|
||||
}
|
||||
|
@ -144,37 +194,63 @@ final internal class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
return
|
||||
}
|
||||
connectionID = String(data: data, encoding: String.Encoding.utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
doRequest(pathComonent: "/idel/\(connectionID!)/0", data: Data([0x00]), completionHandler: didIdel0)
|
||||
doRequest("/idel/\(connectionID!)/0", Data([0x00]), didIdel0)
|
||||
if (logger.isEnabledForLogLevel(.verbose)) {
|
||||
logger.verbose("\(data.bytes):\(response)")
|
||||
}
|
||||
}
|
||||
|
||||
internal func didIdel0(data:Data?, response:URLResponse?, error:Error?) {
|
||||
logger.info("\(data?.bytes):\(response):\(error)")
|
||||
private func didIdel0(data:Data?, response:URLResponse?, error:Error?) {
|
||||
if let error:Error = error {
|
||||
logger.error("\(error)")
|
||||
}
|
||||
connected = true
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: idel)
|
||||
if (logger.isEnabledForLogLevel(.verbose)) {
|
||||
logger.verbose("\(data?.bytes):\(response)")
|
||||
}
|
||||
}
|
||||
|
||||
private func didClose(data:Data?, response:URLResponse?, error:Error?) {
|
||||
if let error:Error = error {
|
||||
logger.error("\(error)")
|
||||
}
|
||||
connected = false
|
||||
if (logger.isEnabledForLogLevel(.verbose)) {
|
||||
logger.verbose("\(data?.bytes):\(response)")
|
||||
}
|
||||
}
|
||||
|
||||
private func didIdel(data:Data?, response:URLResponse?, error:Error?) {
|
||||
listen(data: data, response: response, error: error)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: idel)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
final private func doOutput(bytes:[UInt8]) -> Int {
|
||||
guard let connectionID:String = connectionID else {
|
||||
guard let connectionID:String = connectionID, connected else {
|
||||
return 0
|
||||
}
|
||||
index += 1
|
||||
doRequest(pathComonent: "/send/\(connectionID)/\(index)", data: Data(bytes), completionHandler: listen)
|
||||
let index:Int64 = OSAtomicIncrement64(&self.index)
|
||||
doRequest("/send/\(connectionID)/\(index)", Data(c2packet + bytes), listen)
|
||||
c2packet.removeAll()
|
||||
return bytes.count
|
||||
}
|
||||
|
||||
private func idel() {
|
||||
guard let connectionID:String = connectionID else {
|
||||
guard let connectionID:String = connectionID, connected else {
|
||||
return
|
||||
}
|
||||
index += 1
|
||||
doRequest(pathComonent: "/idel/\(connectionID)/\(index)", data: Data([0x00]), completionHandler: listen)
|
||||
let index:Int64 = OSAtomicIncrement64(&self.index)
|
||||
doRequest("/idel/\(connectionID)/\(index)", Data([0x00]), didIdel)
|
||||
}
|
||||
|
||||
private func doRequest(pathComonent: String, data:Data, completionHandler: ((Data?, URLResponse?, Error?) -> Void)) {
|
||||
private func doRequest(_ pathComonent: String,_ data:Data,_ completionHandler: ((Data?, URLResponse?, Error?) -> Void)) {
|
||||
var request:URLRequest = URLRequest(url: baseURL.appendingPathComponent(pathComonent))
|
||||
request.httpMethod = "POST"
|
||||
let task:URLSessionUploadTask = session.uploadTask(with: request, from: data, completionHandler: completionHandler)
|
||||
task.resume()
|
||||
logger.verbose("\(request)")
|
||||
session.uploadTask(with: request, from: data, completionHandler: completionHandler).resume()
|
||||
if (logger.isEnabledForLogLevel(.verbose)) {
|
||||
logger.verbose("\(request)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,11 @@
|
|||
2901A4EE1D437170002BBD23 /* ClockedQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2901A4ED1D437170002BBD23 /* ClockedQueue.swift */; };
|
||||
2901A4EF1D437662002BBD23 /* ClockedQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2901A4ED1D437170002BBD23 /* ClockedQueue.swift */; };
|
||||
2915EC4D1D85BB8C00621092 /* RTMPTSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294852551D84BFAD002DE492 /* RTMPTSocket.swift */; };
|
||||
2915EC541D85BDF100621092 /* ReplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2915EC531D85BDF100621092 /* ReplayKit.framework */; };
|
||||
2915EC601D85BDF100621092 /* ReplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2915EC531D85BDF100621092 /* ReplayKit.framework */; };
|
||||
2915EC621D85BDF100621092 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2915EC611D85BDF100621092 /* UIKit.framework */; };
|
||||
2915EC6C1D85BDF100621092 /* ScreencastUI.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 2915EC5F1D85BDF100621092 /* ScreencastUI.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
2915EC6F1D85BDF100621092 /* Screencast.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 2915EC521D85BDF100621092 /* Screencast.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
291F4E381CF206E600F59C51 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 291F4E361CF206E200F59C51 /* Icon.png */; };
|
||||
2923A1F31D63004E0019FBCD /* VisualEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2965436A1D62FEB700734698 /* VisualEffect.swift */; };
|
||||
2923A1F41D6300510019FBCD /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296543691D62FEB700734698 /* MainWindowController.swift */; };
|
||||
|
@ -25,6 +30,8 @@
|
|||
2931204E1D4522E400B14211 /* RTSPResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2931204D1D4522E400B14211 /* RTSPResponse.swift */; };
|
||||
2931204F1D4529F900B14211 /* RTSPRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2931204B1D4522CF00B14211 /* RTSPRequest.swift */; };
|
||||
293120501D4529FB00B14211 /* RTSPResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2931204D1D4522E400B14211 /* RTSPResponse.swift */; };
|
||||
293C74371D85D56D001ED43C /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 293C74361D85D56D001ED43C /* MainInterface.storyboard */; };
|
||||
293C74381D85DA4B001ED43C /* lf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2945CBBD1B4BE66000104112 /* lf.framework */; };
|
||||
2942424D1CF4C01300D65DCB /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2942424C1CF4C01300D65DCB /* MD5.swift */; };
|
||||
2942424F1CF4C02300D65DCB /* MD5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2942424E1CF4C02300D65DCB /* MD5Tests.swift */; };
|
||||
294852571D852499002DE492 /* RTMPTSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294852551D84BFAD002DE492 /* RTMPTSocket.swift */; };
|
||||
|
@ -73,6 +80,9 @@
|
|||
299AE0E71D45003D00D26A49 /* RTSPSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299AE0E41D44EC7800D26A49 /* RTSPSocket.swift */; };
|
||||
299B131D1D35272D00A1E8F5 /* ScreenCaptureSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B131C1D35272D00A1E8F5 /* ScreenCaptureSession.swift */; };
|
||||
299B13271D3B751400A1E8F5 /* LFView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B13261D3B751400A1E8F5 /* LFView.swift */; };
|
||||
29A39C8E1D85BF6F007C27E9 /* BroadcastViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A39C831D85BF21007C27E9 /* BroadcastViewController.swift */; };
|
||||
29A39C901D85BF9C007C27E9 /* SampleHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A39C8A1D85BF30007C27E9 /* SampleHandler.swift */; };
|
||||
29A39C921D85CF5F007C27E9 /* RTMPSampleHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A39C911D85CF5E007C27E9 /* RTMPSampleHandler.swift */; };
|
||||
29AF3FCF1D7C744C00E41212 /* NetStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29AF3FCE1D7C744C00E41212 /* NetStream.swift */; };
|
||||
29AF3FD01D7C745200E41212 /* NetStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29AF3FCE1D7C744C00E41212 /* NetStream.swift */; };
|
||||
29B8765B1CD70A7900FC07DA /* AACEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B876571CD70A7900FC07DA /* AACEncoder.swift */; };
|
||||
|
@ -190,6 +200,20 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
2915EC6A1D85BDF100621092 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 2945CBB41B4BE66000104112 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 2915EC5E1D85BDF100621092;
|
||||
remoteInfo = ScreencastUI;
|
||||
};
|
||||
2915EC6D1D85BDF100621092 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 2945CBB41B4BE66000104112 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 2915EC511D85BDF100621092;
|
||||
remoteInfo = Screencast;
|
||||
};
|
||||
29798E5F1CE60E5300F5CBD0 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 2945CBB41B4BE66000104112 /* Project object */;
|
||||
|
@ -221,6 +245,18 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
2915EC761D85BDF200621092 /* Embed App Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
2915EC6C1D85BDF100621092 /* ScreencastUI.appex in Embed App Extensions */,
|
||||
2915EC6F1D85BDF100621092 /* Screencast.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
29EF037B1CD79B3900473D99 /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -239,11 +275,16 @@
|
|||
1363274A77A734C669D6055F /* Pods-Tests Objective-C.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests Objective-C.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests Objective-C/Pods-Tests Objective-C.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
1DF7E7E9A4DEEF0DE28197B7 /* Pods-Example macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example macOS/Pods-Example macOS.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
2901A4ED1D437170002BBD23 /* ClockedQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ClockedQueue.swift; path = Sources/Util/ClockedQueue.swift; sourceTree = SOURCE_ROOT; };
|
||||
2915EC521D85BDF100621092 /* Screencast.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Screencast.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2915EC531D85BDF100621092 /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; };
|
||||
2915EC5F1D85BDF100621092 /* ScreencastUI.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ScreencastUI.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2915EC611D85BDF100621092 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
291F4E361CF206E200F59C51 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Examples/iOS/Icon.png; sourceTree = "<group>"; };
|
||||
2923A1FA1D63011E0019FBCD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Examples/macOS/Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
29245AEC1D3233EB00AFFB9A /* VideoGravityUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = VideoGravityUtil.swift; path = Sources/Util/VideoGravityUtil.swift; sourceTree = SOURCE_ROOT; };
|
||||
2931204B1D4522CF00B14211 /* RTSPRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RTSPRequest.swift; path = Sources/RTSP/RTSPRequest.swift; sourceTree = SOURCE_ROOT; };
|
||||
2931204D1D4522E400B14211 /* RTSPResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RTSPResponse.swift; path = Sources/RTSP/RTSPResponse.swift; sourceTree = SOURCE_ROOT; };
|
||||
293C74361D85D56D001ED43C /* MainInterface.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = MainInterface.storyboard; path = Examples/iOS/ScreencastUI/Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
|
||||
2942424C1CF4C01300D65DCB /* MD5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MD5.swift; path = Sources/Util/MD5.swift; sourceTree = SOURCE_ROOT; };
|
||||
2942424E1CF4C02300D65DCB /* MD5Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MD5Tests.swift; sourceTree = "<group>"; };
|
||||
2945CBBD1B4BE66000104112 /* lf.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = lf.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -287,6 +328,11 @@
|
|||
299B13261D3B751400A1E8F5 /* LFView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LFView.swift; path = Platforms/iOS/LFView.swift; sourceTree = "<group>"; };
|
||||
299F7E3A1CD71A97001E7272 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Platforms/iOS/Info.plist; sourceTree = "<group>"; };
|
||||
299F7E3B1CD71A97001E7272 /* lf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lf.h; path = Platforms/iOS/lf.h; sourceTree = "<group>"; };
|
||||
29A39C831D85BF21007C27E9 /* BroadcastViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BroadcastViewController.swift; path = Examples/iOS/ScreencastUI/BroadcastViewController.swift; sourceTree = "<group>"; };
|
||||
29A39C841D85BF21007C27E9 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Examples/iOS/ScreencastUI/Info.plist; sourceTree = "<group>"; };
|
||||
29A39C881D85BF30007C27E9 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Examples/iOS/Screencast/Info.plist; sourceTree = "<group>"; };
|
||||
29A39C8A1D85BF30007C27E9 /* SampleHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SampleHandler.swift; path = Examples/iOS/Screencast/SampleHandler.swift; sourceTree = "<group>"; };
|
||||
29A39C911D85CF5E007C27E9 /* RTMPSampleHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RTMPSampleHandler.swift; path = Platforms/iOS/RTMPSampleHandler.swift; sourceTree = "<group>"; };
|
||||
29AF3FCE1D7C744C00E41212 /* NetStream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NetStream.swift; path = Sources/Net/NetStream.swift; sourceTree = SOURCE_ROOT; };
|
||||
29B8761B1CD701F900FC07DA /* lf.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = lf.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
29B876571CD70A7900FC07DA /* AACEncoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AACEncoder.swift; path = Sources/Codec/AACEncoder.swift; sourceTree = SOURCE_ROOT; };
|
||||
|
@ -379,6 +425,24 @@
|
|||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
2915EC4F1D85BDF100621092 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
293C74381D85DA4B001ED43C /* lf.framework in Frameworks */,
|
||||
2915EC541D85BDF100621092 /* ReplayKit.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2915EC5C1D85BDF100621092 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2915EC601D85BDF100621092 /* ReplayKit.framework in Frameworks */,
|
||||
2915EC621D85BDF100621092 /* UIKit.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
29798E561CE60E5300F5CBD0 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -438,11 +502,13 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
FBC39416255B1FE34117A703 /* Pods_Example_iOS.framework */,
|
||||
E0E97FC4AB6F64C73316C830 /* Pods_Example_macOS.framework */,
|
||||
D006C358F97A4A666838EE0F /* Pods_lf_iOS.framework */,
|
||||
2BCF2681D710136C3A3DC598 /* Pods_lf_macOS.framework */,
|
||||
344B89622957B99E2DE08F44 /* Pods_Tests_Objective_C.framework */,
|
||||
E9A43EC150DE78951CDBB12F /* Pods_Tests.framework */,
|
||||
E0E97FC4AB6F64C73316C830 /* Pods_Example_macOS.framework */,
|
||||
2BCF2681D710136C3A3DC598 /* Pods_lf_macOS.framework */,
|
||||
2915EC531D85BDF100621092 /* ReplayKit.framework */,
|
||||
2915EC611D85BDF100621092 /* UIKit.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
|
@ -571,6 +637,8 @@
|
|||
29C932941CD76FD300283FC5 /* Example macOS.app */,
|
||||
29798E591CE60E5300F5CBD0 /* Tests.xctest */,
|
||||
29BA5B8E1D50BEAD00A51EA8 /* Tests Objective-C.xctest */,
|
||||
2915EC521D85BDF100621092 /* Screencast.appex */,
|
||||
2915EC5F1D85BDF100621092 /* ScreencastUI.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -673,6 +741,8 @@
|
|||
2968974D1CDB01DD0074D5F0 /* LaunchScreen.storyboard */,
|
||||
296897441CDB01D20074D5F0 /* LiveViewController.swift */,
|
||||
296897451CDB01D20074D5F0 /* PreferenceController.swift */,
|
||||
29A39C801D85BEFA007C27E9 /* Screencast */,
|
||||
29A39C811D85BF07007C27E9 /* ScreencastUI */,
|
||||
296897461CDB01D20074D5F0 /* VisualEffect.swift */,
|
||||
);
|
||||
name = iOS;
|
||||
|
@ -743,11 +813,31 @@
|
|||
299F7E3A1CD71A97001E7272 /* Info.plist */,
|
||||
299F7E3B1CD71A97001E7272 /* lf.h */,
|
||||
299B13261D3B751400A1E8F5 /* LFView.swift */,
|
||||
29A39C911D85CF5E007C27E9 /* RTMPSampleHandler.swift */,
|
||||
299B131C1D35272D00A1E8F5 /* ScreenCaptureSession.swift */,
|
||||
);
|
||||
name = iOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
29A39C801D85BEFA007C27E9 /* Screencast */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
29A39C881D85BF30007C27E9 /* Info.plist */,
|
||||
29A39C8A1D85BF30007C27E9 /* SampleHandler.swift */,
|
||||
);
|
||||
name = Screencast;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
29A39C811D85BF07007C27E9 /* ScreencastUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
293C74361D85D56D001ED43C /* MainInterface.storyboard */,
|
||||
29A39C831D85BF21007C27E9 /* BroadcastViewController.swift */,
|
||||
29A39C841D85BF21007C27E9 /* Info.plist */,
|
||||
);
|
||||
name = ScreencastUI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
29BA5B8F1D50BEAD00A51EA8 /* Tests Objective-C */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -845,6 +935,40 @@
|
|||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
2915EC511D85BDF100621092 /* Screencast */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2915EC751D85BDF200621092 /* Build configuration list for PBXNativeTarget "Screencast" */;
|
||||
buildPhases = (
|
||||
2915EC4E1D85BDF100621092 /* Sources */,
|
||||
2915EC4F1D85BDF100621092 /* Frameworks */,
|
||||
2915EC501D85BDF100621092 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Screencast;
|
||||
productName = Screencast;
|
||||
productReference = 2915EC521D85BDF100621092 /* Screencast.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
2915EC5E1D85BDF100621092 /* ScreencastUI */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2915EC741D85BDF200621092 /* Build configuration list for PBXNativeTarget "ScreencastUI" */;
|
||||
buildPhases = (
|
||||
2915EC5B1D85BDF100621092 /* Sources */,
|
||||
2915EC5C1D85BDF100621092 /* Frameworks */,
|
||||
2915EC5D1D85BDF100621092 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ScreencastUI;
|
||||
productName = ScreencastUI;
|
||||
productReference = 2915EC5F1D85BDF100621092 /* ScreencastUI.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
2945CBBC1B4BE66000104112 /* lf iOS */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2945CBD31B4BE66000104112 /* Build configuration list for PBXNativeTarget "lf iOS" */;
|
||||
|
@ -939,11 +1063,14 @@
|
|||
29EF037B1CD79B3900473D99 /* Embed Frameworks */,
|
||||
CBA1142FD353CCE1FB45B041 /* [CP] Embed Pods Frameworks */,
|
||||
A754678A2865310B7C0AE51F /* [CP] Copy Pods Resources */,
|
||||
2915EC761D85BDF200621092 /* Embed App Extensions */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
29C932A91CD78B5500283FC5 /* PBXTargetDependency */,
|
||||
2915EC6B1D85BDF100621092 /* PBXTargetDependency */,
|
||||
2915EC6E1D85BDF100621092 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Example iOS";
|
||||
productName = "Example iOS";
|
||||
|
@ -977,10 +1104,20 @@
|
|||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftMigration = 0700;
|
||||
LastSwiftUpdateCheck = 0730;
|
||||
LastSwiftUpdateCheck = 0800;
|
||||
LastUpgradeCheck = 0800;
|
||||
ORGANIZATIONNAME = "Shogo Endo";
|
||||
TargetAttributes = {
|
||||
2915EC511D85BDF100621092 = {
|
||||
CreatedOnToolsVersion = 8.0;
|
||||
DevelopmentTeam = SUEQ2SZ2L5;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
2915EC5E1D85BDF100621092 = {
|
||||
CreatedOnToolsVersion = 8.0;
|
||||
DevelopmentTeam = SUEQ2SZ2L5;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
2945CBBC1B4BE66000104112 = {
|
||||
CreatedOnToolsVersion = 6.4;
|
||||
LastSwiftMigration = 0800;
|
||||
|
@ -1024,6 +1161,8 @@
|
|||
29B8761A1CD701F900FC07DA /* lf macOS */,
|
||||
29C9327D1CD76FB800283FC5 /* Example iOS */,
|
||||
29C932931CD76FD300283FC5 /* Example macOS */,
|
||||
2915EC511D85BDF100621092 /* Screencast */,
|
||||
2915EC5E1D85BDF100621092 /* ScreencastUI */,
|
||||
29798E581CE60E5300F5CBD0 /* Tests */,
|
||||
29BA5B8D1D50BEAD00A51EA8 /* Tests Objective-C */,
|
||||
);
|
||||
|
@ -1031,6 +1170,21 @@
|
|||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
2915EC501D85BDF100621092 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2915EC5D1D85BDF100621092 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
293C74371D85D56D001ED43C /* MainInterface.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2945CBBB1B4BE66000104112 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -1327,6 +1481,22 @@
|
|||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
2915EC4E1D85BDF100621092 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
29A39C901D85BF9C007C27E9 /* SampleHandler.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2915EC5B1D85BDF100621092 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
29A39C8E1D85BF6F007C27E9 /* BroadcastViewController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2945CBB81B4BE66000104112 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -1360,6 +1530,7 @@
|
|||
29B876AF1CD70B2800FC07DA /* RTMPChunk.swift in Sources */,
|
||||
29B876841CD70AE800FC07DA /* H264+AVC.swift in Sources */,
|
||||
29B8769B1CD70B1100FC07DA /* MIME.swift in Sources */,
|
||||
29A39C921D85CF5F007C27E9 /* RTMPSampleHandler.swift in Sources */,
|
||||
29B8769C1CD70B1100FC07DA /* NetClient.swift in Sources */,
|
||||
29B8767C1CD70ACE00FC07DA /* TSWriter.swift in Sources */,
|
||||
29B876871CD70AE800FC07DA /* ProgramSpecific.swift in Sources */,
|
||||
|
@ -1531,6 +1702,16 @@
|
|||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
2915EC6B1D85BDF100621092 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 2915EC5E1D85BDF100621092 /* ScreencastUI */;
|
||||
targetProxy = 2915EC6A1D85BDF100621092 /* PBXContainerItemProxy */;
|
||||
};
|
||||
2915EC6E1D85BDF100621092 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 2915EC511D85BDF100621092 /* Screencast */;
|
||||
targetProxy = 2915EC6D1D85BDF100621092 /* PBXContainerItemProxy */;
|
||||
};
|
||||
29798E601CE60E5300F5CBD0 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 29B8761A1CD701F900FC07DA /* lf macOS */;
|
||||
|
@ -1573,6 +1754,86 @@
|
|||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
2915EC701D85BDF200621092 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = SUEQ2SZ2L5;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Examples/iOS/Screencast/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.shogo4405.lf.Example-iOS.Screencast";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2915EC711D85BDF200621092 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
DEVELOPMENT_TEAM = SUEQ2SZ2L5;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Examples/iOS/Screencast/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.shogo4405.lf.Example-iOS.Screencast";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
2915EC721D85BDF200621092 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = SUEQ2SZ2L5;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Examples/iOS/ScreencastUI/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.shogo4405.lf.Example-iOS.ScreencastUI";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2915EC731D85BDF200621092 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
DEVELOPMENT_TEAM = SUEQ2SZ2L5;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Examples/iOS/ScreencastUI/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.shogo4405.lf.Example-iOS.ScreencastUI";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
2945CBD11B4BE66000104112 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
@ -1930,6 +2191,24 @@
|
|||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
2915EC741D85BDF200621092 /* Build configuration list for PBXNativeTarget "ScreencastUI" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2915EC721D85BDF200621092 /* Debug */,
|
||||
2915EC731D85BDF200621092 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
2915EC751D85BDF200621092 /* Build configuration list for PBXNativeTarget "Screencast" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2915EC701D85BDF200621092 /* Debug */,
|
||||
2915EC711D85BDF200621092 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
2945CBB71B4BE66000104112 /* Build configuration list for PBXProject "lf" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
|
Loading…
Reference in New Issue