fix MP4Reader
This commit is contained in:
parent
daabefc352
commit
523b92f401
|
@ -10,7 +10,7 @@
|
|||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Examples lf</string>
|
||||
<string>HaishinKit</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
<?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">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="ObA-dk-sSI">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
|
@ -18,15 +21,15 @@
|
|||
<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"/>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="rtmp://192.168.179.3:1935/live" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="GKU-M2-aRK">
|
||||
<rect key="frame" x="16" y="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"/>
|
||||
<rect key="frame" x="252" y="59" width="34" height="30"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<state key="normal" title="Start"/>
|
||||
</button>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Examples lf</string>
|
||||
<string>HaishinKit</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
|
|
@ -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.3:1935/live"
|
||||
|
||||
var enabledSharedObject:Bool = false
|
||||
var rtmpConnection:RTMPConnection = RTMPConnection()
|
||||
|
@ -85,10 +85,8 @@ final class LiveViewController: NSViewController {
|
|||
audioPopUpButton.target = self
|
||||
cameraPopUpButton.target = self
|
||||
rtmpStream = RTMPStream(connection: rtmpConnection)
|
||||
rtmpStream.attachAudio(DeviceUtil.device(withLocalizedName: audioPopUpButton.itemTitles[audioPopUpButton.indexOfSelectedItem], mediaType: AVMediaTypeAudio)
|
||||
)
|
||||
rtmpStream.attachCamera(DeviceUtil.device(withLocalizedName: cameraPopUpButton.itemTitles[cameraPopUpButton.indexOfSelectedItem], mediaType: AVMediaTypeVideo)
|
||||
)
|
||||
rtmpStream.attachAudio(DeviceUtil.device(withLocalizedName: audioPopUpButton.itemTitles[audioPopUpButton.indexOfSelectedItem], mediaType: AVMediaTypeAudio))
|
||||
rtmpStream.attachCamera(DeviceUtil.device(withLocalizedName: cameraPopUpButton.itemTitles[cameraPopUpButton.indexOfSelectedItem], mediaType: AVMediaTypeVideo))
|
||||
rtmpStream.addObserver(self, forKeyPath: "currentFPS", options: .new, context: nil)
|
||||
publishButton.target = self
|
||||
|
||||
|
|
|
@ -623,7 +623,7 @@ final class MP4TrakReader {
|
|||
if let stss:MP4SyncSampleBox = stss as? MP4SyncSampleBox {
|
||||
var keyframes:[UInt32] = stss.entries
|
||||
for i in 0..<keyframes.count {
|
||||
keyframe[Int(keyframes[i])] = true
|
||||
keyframe[Int(keyframes[i]) - 1] = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -650,11 +650,9 @@ final class MP4TrakReader {
|
|||
|
||||
var index:Int = 0
|
||||
let count:Int = sampleToChunk.count
|
||||
|
||||
for i in 0..<count {
|
||||
let j:Int = Int(sampleToChunk[i].firstChunk) - 1
|
||||
let m:Int = (i + 1 < count) ? Int(sampleToChunk[i + 1].firstChunk) - 1 : offsets.count
|
||||
for _ in j..<m {
|
||||
for j in (Int(sampleToChunk[i].firstChunk) - 1)..<m {
|
||||
var offset:UInt32 = offsets[j]
|
||||
for _ in 0..<sampleToChunk[i].samplesPerChunk {
|
||||
self.offset.append(offset)
|
||||
|
|
|
@ -18,6 +18,9 @@ final class RTMPMuxer {
|
|||
fileprivate var videoTimestamp:CMTime = kCMTimeZero
|
||||
|
||||
func dispose() {
|
||||
avcC = nil
|
||||
audioDecorderSpecificConfig = nil
|
||||
timestamps.removeAll()
|
||||
audioTimestamp = kCMTimeZero
|
||||
videoTimestamp = kCMTimeZero
|
||||
}
|
||||
|
@ -25,7 +28,6 @@ final class RTMPMuxer {
|
|||
|
||||
extension RTMPMuxer: AudioEncoderDelegate {
|
||||
// MARK: AudioEncoderDelegate
|
||||
|
||||
func didSetFormatDescription(audio formatDescription: CMFormatDescription?) {
|
||||
guard let formatDescription:CMFormatDescription = formatDescription else {
|
||||
return
|
||||
|
@ -105,7 +107,6 @@ extension RTMPMuxer: MP4SamplerDelegate {
|
|||
if (avcC == self.avcC) {
|
||||
return
|
||||
}
|
||||
logger.info("\(avcC)")
|
||||
var buffer:Data = Data([FLVFrameType.key.rawValue << 4 | FLVVideoCodec.avc.rawValue, FLVAVCPacketType.seq.rawValue, 0, 0, 0])
|
||||
buffer.append(avcC)
|
||||
delegate?.sampleOutput(video: buffer, withTimestamp: 0, muxer: self)
|
||||
|
@ -119,7 +120,7 @@ extension RTMPMuxer: MP4SamplerDelegate {
|
|||
if (audioDecorderSpecificConfig == self.audioDecorderSpecificConfig) {
|
||||
return
|
||||
}
|
||||
var buffer:Data = Data([RTMPMuxer.aac, FLVAACPacketType.raw.rawValue])
|
||||
var buffer:Data = Data([RTMPMuxer.aac, FLVAACPacketType.seq.rawValue])
|
||||
buffer.append(audioDecorderSpecificConfig)
|
||||
delegate?.sampleOutput(audio: buffer, withTimestamp: 0, muxer: self)
|
||||
self.audioDecorderSpecificConfig = audioDecorderSpecificConfig
|
||||
|
|
|
@ -27,6 +27,8 @@ protocol RTMPSocketDelegate: IEventDispatcher {
|
|||
// MARK: -
|
||||
final class RTMPSocket: NetSocket, RTMPSocketCompatible {
|
||||
|
||||
static let defaultBufferSize:Int = 1024
|
||||
|
||||
enum ReadyState: UInt8 {
|
||||
case uninitialized = 0
|
||||
case versionSent = 1
|
||||
|
@ -36,8 +38,6 @@ final class RTMPSocket: NetSocket, RTMPSocketCompatible {
|
|||
case closed = 5
|
||||
}
|
||||
|
||||
static let defaultBufferSize:Int = 1024
|
||||
|
||||
var readyState:ReadyState = .uninitialized {
|
||||
didSet {
|
||||
delegate?.didSet(readyState: readyState)
|
||||
|
|
|
@ -6,11 +6,8 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
var timeout:Int64 = 0
|
||||
var chunkSizeC:Int = RTMPChunk.defaultSize
|
||||
var chunkSizeS:Int = RTMPChunk.defaultSize
|
||||
var totalBytesIn:Int64 = 0
|
||||
var totalBytesOut:Int64 = 0
|
||||
var inputBuffer:[UInt8] = []
|
||||
var securityLevel:StreamSocketSecurityLevel = .none
|
||||
var objectEncoding:UInt8 = 0x00
|
||||
weak var delegate:RTMPSocketDelegate? = nil
|
||||
var connected:Bool = false {
|
||||
didSet {
|
||||
|
@ -20,6 +17,7 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
readyState = .versionSent
|
||||
return
|
||||
}
|
||||
timer = nil
|
||||
readyState = .closed
|
||||
for event in events {
|
||||
delegate?.dispatch(event: event)
|
||||
|
@ -27,7 +25,7 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
events.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var timestamp:TimeInterval {
|
||||
return handshake.timestamp
|
||||
}
|
||||
|
@ -38,18 +36,32 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
}
|
||||
}
|
||||
|
||||
fileprivate(set) var totalBytesIn:Int64 = 0
|
||||
fileprivate(set) var totalBytesOut:Int64 = 0
|
||||
fileprivate var timer:Timer? {
|
||||
didSet {
|
||||
if let oldValue:Timer = oldValue {
|
||||
oldValue.invalidate()
|
||||
}
|
||||
if let timer:Timer = timer {
|
||||
RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var delay:UInt8 = 1
|
||||
private var index:Int64 = 0
|
||||
private var events:[Event] = []
|
||||
private var baseURL:URL!
|
||||
private var session:URLSession!
|
||||
private var request:URLRequest!
|
||||
private var c2packet:[UInt8] = []
|
||||
private var isPending:Bool = false
|
||||
private var handshake:RTMPHandshake = RTMPHandshake()
|
||||
private let outputQueue:DispatchQueue = DispatchQueue(label: "com.github.shgoo4405.lf.RTMPTSocket.output")
|
||||
private var connectionID:String!
|
||||
private var connectionID:String?
|
||||
private var isRequesting:Bool = false
|
||||
private var outputBuffer:[UInt8] = []
|
||||
private var lastResponse:Date = Date()
|
||||
private var handshake:RTMPHandshake = RTMPHandshake()
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
@ -63,9 +75,10 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
"User-Agent": "Shockwave Flash",
|
||||
]
|
||||
let scheme:String = securityLevel == .none ? "http" : "https"
|
||||
session = URLSession(configuration: config)
|
||||
session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
|
||||
baseURL = URL(string: "\(scheme)://\(withName):\(port)")!
|
||||
doRequest("/fcs/ident2", Data([0x00]), didIdent2)
|
||||
timer = Timer(timeInterval: 0.1, target: self, selector: #selector(RTMPTSocket.on(timer:)), userInfo: nil, repeats: true)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
|
@ -77,8 +90,7 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
}
|
||||
outputQueue.sync {
|
||||
self.outputBuffer.append(contentsOf: bytes)
|
||||
if (!self.isPending) {
|
||||
self.isPending = true
|
||||
if (!self.isRequesting) {
|
||||
self.doOutput(bytes: self.outputBuffer)
|
||||
self.outputBuffer.removeAll()
|
||||
}
|
||||
|
@ -103,6 +115,9 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
}
|
||||
|
||||
private func listen(data:Data?, response:URLResponse?, error:Error?) {
|
||||
|
||||
lastResponse = Date()
|
||||
|
||||
if (logger.isEnabledFor(level: .verbose)) {
|
||||
logger.verbose("\(data):\(response):\(error)")
|
||||
}
|
||||
|
@ -112,10 +127,9 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
return
|
||||
}
|
||||
|
||||
lastResponse = Date()
|
||||
outputQueue.sync {
|
||||
if (self.outputBuffer.isEmpty) {
|
||||
self.isPending = false
|
||||
self.isRequesting = false
|
||||
} else {
|
||||
self.doOutput(bytes: outputBuffer)
|
||||
self.outputBuffer.removeAll()
|
||||
|
@ -130,6 +144,7 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
}
|
||||
|
||||
var buffer:[UInt8] = data.bytes
|
||||
OSAtomicAdd64(Int64(buffer.count), &totalBytesIn)
|
||||
delay = buffer.remove(at: 0)
|
||||
inputBuffer.append(contentsOf: buffer)
|
||||
|
||||
|
@ -178,13 +193,13 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
return
|
||||
}
|
||||
connectionID = String(data: data, encoding: String.Encoding.utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
doRequest("/idel/\(connectionID!)/0", Data([0x00]), didIdel0)
|
||||
doRequest("/idle/\(connectionID!)/0", Data([0x00]), didIdle0)
|
||||
if (logger.isEnabledFor(level: .verbose)) {
|
||||
logger.verbose("\(data.bytes):\(response)")
|
||||
}
|
||||
}
|
||||
|
||||
private func didIdel0(data:Data?, response:URLResponse?, error:Error?) {
|
||||
private func didIdle0(data:Data?, response:URLResponse?, error:Error?) {
|
||||
if let error:Error = error {
|
||||
logger.error("\(error)")
|
||||
}
|
||||
|
@ -204,17 +219,23 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
}
|
||||
}
|
||||
|
||||
private func idel() {
|
||||
private func idle() {
|
||||
guard let connectionID:String = connectionID, connected else {
|
||||
return
|
||||
}
|
||||
let index:Int64 = OSAtomicIncrement64(&self.index)
|
||||
doRequest("/idel/\(connectionID)/\(index)", Data([0x00]), didIdel)
|
||||
doRequest("/idle/\(connectionID)/\(index)", Data([0x00]), didIdle)
|
||||
}
|
||||
|
||||
private func didIdel(data:Data?, response:URLResponse?, error:Error?) {
|
||||
private func didIdle(data:Data?, response:URLResponse?, error:Error?) {
|
||||
listen(data: data, response: response, error: error)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: idel)
|
||||
}
|
||||
|
||||
@objc private func on(timer:Timer) {
|
||||
guard (Double(delay) / 60) < abs(lastResponse.timeIntervalSinceNow), !isRequesting else {
|
||||
return
|
||||
}
|
||||
idle()
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
|
@ -229,11 +250,19 @@ final class RTMPTSocket: NSObject, RTMPSocketCompatible {
|
|||
}
|
||||
|
||||
private func doRequest(_ pathComonent: String,_ data:Data,_ completionHandler: @escaping ((Data?, URLResponse?, Error?) -> Void)) {
|
||||
var request:URLRequest = URLRequest(url: baseURL.appendingPathComponent(pathComonent))
|
||||
isRequesting = true
|
||||
request = URLRequest(url: baseURL.appendingPathComponent(pathComonent))
|
||||
request.httpMethod = "POST"
|
||||
session.uploadTask(with: request, from: data, completionHandler: completionHandler).resume()
|
||||
if (logger.isEnabledFor(level: .verbose)) {
|
||||
logger.verbose("\(request)")
|
||||
logger.verbose("\(self.request)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
extension RTMPTSocket: URLSessionTaskDelegate {
|
||||
func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
|
||||
OSAtomicAdd64(bytesSent, &totalBytesOut)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import XCTest
|
|||
@testable import lf
|
||||
|
||||
final class MP4SamplerTests: XCTestCase {
|
||||
func testMain() {
|
||||
func main() {
|
||||
let bundle:Bundle = Bundle(for: type(of: self))
|
||||
let url:URL = URL(fileURLWithPath: bundle.path(forResource: "SampleVideo_360x240_5mb", ofType: "mp4")!)
|
||||
let sampler:MP4Sampler = MP4Sampler()
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
import Foundation
|
||||
import XCTest
|
||||
|
||||
@testable import lf
|
||||
|
||||
final class RTMPConnectionTests: XCTestCase {
|
||||
func testPublish() {
|
||||
let bundle:Bundle = Bundle(for: type(of: self))
|
||||
let url:URL = URL(fileURLWithPath: bundle.path(forResource: "SampleVideo_360x240_5mb-base", ofType: "mp4")!)
|
||||
let connection:RTMPConnection = RTMPConnection()
|
||||
let stream:RTMPStream = RTMPStream(connection: connection)
|
||||
connection.connect("rtmp://localhost:1935/live")
|
||||
stream.appendFile(url)
|
||||
stream.publish("live")
|
||||
sleep(10000)
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -4,7 +4,7 @@ import XCTest
|
|||
@testable import lf
|
||||
|
||||
final class TimerDriverTests: XCTestCase {
|
||||
func testMain() {
|
||||
func main() {
|
||||
let timerDriver:TimerDriver = TimerDriver()
|
||||
let delegate:TimerDriverDelegate = LoggerTimerDriverDelegate()
|
||||
timerDriver.delegate = delegate
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
/* Begin PBXBuildFile section */
|
||||
2901A4EE1D437170002BBD23 /* ClockedQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2901A4ED1D437170002BBD23 /* ClockedQueue.swift */; };
|
||||
2901A4EF1D437662002BBD23 /* ClockedQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2901A4ED1D437170002BBD23 /* ClockedQueue.swift */; };
|
||||
290686031DFDB7A7008EB7ED /* RTMPConnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 290686021DFDB7A6008EB7ED /* RTMPConnectionTests.swift */; };
|
||||
290686051DFDC19B008EB7ED /* SampleVideo_360x240_5mb-base.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 290686041DFDC19B008EB7ED /* SampleVideo_360x240_5mb-base.mp4 */; };
|
||||
290EA8901DFB616000053022 /* Foundation+ExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 290EA88E1DFB616000053022 /* Foundation+ExtensionTests.swift */; };
|
||||
290EA8911DFB616000053022 /* SwiftCore+ExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 290EA88F1DFB616000053022 /* SwiftCore+ExtensionTests.swift */; };
|
||||
290EA8931DFB617800053022 /* HTTPRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 290EA8921DFB617800053022 /* HTTPRequestTests.swift */; };
|
||||
|
@ -100,7 +102,7 @@
|
|||
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 */; };
|
||||
29A39C921D85CF5F007C27E9 /* RTMPSampleHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A39C911D85CF5E007C27E9 /* RTMPSampleHandler.swift */; };
|
||||
29A39C921D85CF5F007C27E9 /* RTMPMP4ClipHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A39C911D85CF5E007C27E9 /* RTMPMP4ClipHandler.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 */; };
|
||||
|
@ -301,6 +303,8 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
2901A4ED1D437170002BBD23 /* ClockedQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ClockedQueue.swift; path = Sources/Util/ClockedQueue.swift; sourceTree = SOURCE_ROOT; };
|
||||
290686021DFDB7A6008EB7ED /* RTMPConnectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RTMPConnectionTests.swift; path = RTMP/RTMPConnectionTests.swift; sourceTree = "<group>"; };
|
||||
290686041DFDC19B008EB7ED /* SampleVideo_360x240_5mb-base.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SampleVideo_360x240_5mb-base.mp4"; sourceTree = "<group>"; };
|
||||
290EA88E1DFB616000053022 /* Foundation+ExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Foundation+ExtensionTests.swift"; path = "Core/Foundation+ExtensionTests.swift"; sourceTree = "<group>"; };
|
||||
290EA88F1DFB616000053022 /* SwiftCore+ExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "SwiftCore+ExtensionTests.swift"; path = "Core/SwiftCore+ExtensionTests.swift"; sourceTree = "<group>"; };
|
||||
290EA8921DFB617800053022 /* HTTPRequestTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = HTTPRequestTests.swift; path = HTTP/HTTPRequestTests.swift; sourceTree = "<group>"; };
|
||||
|
@ -378,7 +382,7 @@
|
|||
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>"; };
|
||||
29A39C911D85CF5E007C27E9 /* RTMPSampleHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RTMPSampleHandler.swift; path = Platforms/iOS/RTMPSampleHandler.swift; sourceTree = "<group>"; };
|
||||
29A39C911D85CF5E007C27E9 /* RTMPMP4ClipHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RTMPMP4ClipHandler.swift; path = Platforms/iOS/RTMPMP4ClipHandler.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; };
|
||||
|
@ -572,6 +576,7 @@
|
|||
290EA89C1DFB61B100053022 /* AMF0SerializerTests.swift */,
|
||||
290EA89D1DFB61B100053022 /* ASClassTests.swift */,
|
||||
290EA89E1DFB61B100053022 /* RTMPChunkTests.swift */,
|
||||
290686021DFDB7A6008EB7ED /* RTMPConnectionTests.swift */,
|
||||
);
|
||||
name = RTMP;
|
||||
sourceTree = "<group>";
|
||||
|
@ -603,6 +608,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
29B876D71CD70CE700FC07DA /* SampleVideo_360x240_5mb */,
|
||||
290686041DFDC19B008EB7ED /* SampleVideo_360x240_5mb-base.mp4 */,
|
||||
29B876D81CD70CE700FC07DA /* SampleVideo_360x240_5mb.m3u8 */,
|
||||
29B876D91CD70CE700FC07DA /* SampleVideo_360x240_5mb.mp4 */,
|
||||
);
|
||||
|
@ -823,7 +829,7 @@
|
|||
299F7E3A1CD71A97001E7272 /* Info.plist */,
|
||||
299F7E3B1CD71A97001E7272 /* lf.h */,
|
||||
299B13261D3B751400A1E8F5 /* LFView.swift */,
|
||||
29A39C911D85CF5E007C27E9 /* RTMPSampleHandler.swift */,
|
||||
29A39C911D85CF5E007C27E9 /* RTMPMP4ClipHandler.swift */,
|
||||
299B131C1D35272D00A1E8F5 /* ScreenCaptureSession.swift */,
|
||||
);
|
||||
name = iOS;
|
||||
|
@ -1179,6 +1185,7 @@
|
|||
files = (
|
||||
29798E751CE614FE00F5CBD0 /* SampleVideo_360x240_5mb in Resources */,
|
||||
29798E761CE614FE00F5CBD0 /* SampleVideo_360x240_5mb.m3u8 in Resources */,
|
||||
290686051DFDC19B008EB7ED /* SampleVideo_360x240_5mb-base.mp4 in Resources */,
|
||||
29798E771CE614FE00F5CBD0 /* SampleVideo_360x240_5mb.mp4 in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -1329,7 +1336,7 @@
|
|||
29B876841CD70AE800FC07DA /* H264+AVC.swift in Sources */,
|
||||
296242621D8DB86500C451A3 /* TSWriter.swift in Sources */,
|
||||
29B8769B1CD70B1100FC07DA /* MIME.swift in Sources */,
|
||||
29A39C921D85CF5F007C27E9 /* RTMPSampleHandler.swift in Sources */,
|
||||
29A39C921D85CF5F007C27E9 /* RTMPMP4ClipHandler.swift in Sources */,
|
||||
29B8769C1CD70B1100FC07DA /* NetClient.swift in Sources */,
|
||||
29B876871CD70AE800FC07DA /* ProgramSpecific.swift in Sources */,
|
||||
298BCF331DD4C44A007FF86A /* AnyUtil.swift in Sources */,
|
||||
|
@ -1395,6 +1402,7 @@
|
|||
290EA8A11DFB61B100053022 /* RTMPChunkTests.swift in Sources */,
|
||||
290EA89F1DFB61B100053022 /* AMF0SerializerTests.swift in Sources */,
|
||||
290EA8AA1DFB61E700053022 /* CRC32Tests.swift in Sources */,
|
||||
290686031DFDB7A7008EB7ED /* RTMPConnectionTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue