Compare commits

...

136 Commits

Author SHA1 Message Date
chenliming a805106ed2 编译不过呀pod 2016-10-21 14:47:39 +08:00
chenliming e1b8812b25 编译问题 2016-10-21 14:44:53 +08:00
chenliming a130058c5d ... 2016-10-21 14:34:49 +08:00
chenliming 3f804634c5 添加build脚本 2016-10-21 14:26:54 +08:00
chenliming 8b39f68a48 update version 2016-10-20 21:16:49 +08:00
chenliming 1d7b1f7073 添加demo 2016-10-20 21:15:49 +08:00
chenliming 47f35058f3 update version 2016-10-12 20:06:02 +08:00
chenliming a1a7e9aeea fix audioCapture crash 2016-10-12 16:22:49 +08:00
chenliming fabae8ddd8 update version 2016-10-09 10:53:38 +08:00
chenliming 12e1066cae update version 2016-10-08 18:37:42 +08:00
chenliming 05ca0f4f4b update version 2016-10-08 17:05:33 +08:00
chenliming 9e536d2291 add status refresh 2016-10-08 17:02:21 +08:00
chenliming 7bb976d4ae fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/108 2016-10-08 16:09:23 +08:00
chenliming 934d3f29ad changed to async 2016-10-08 14:34:36 +08:00
chenliming 87b3244ba5 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/105 2016-10-08 14:33:02 +08:00
小歪~~~ 23824e2b74 Merge pull request #104 from hannseman/master
Fixes deadlock in #100
2016-10-08 14:24:25 +08:00
Hannes Ljungberg 71d68c3e6e Fix deadlock by not checking for isRunning and stopping unit in callback. 2016-10-03 09:51:53 +02:00
小歪~~~ d9887180c3 Merge pull request #103 from ScottieLee/dev
Reset compression session when encoding error occurs
2016-09-30 11:38:33 +08:00
LiSi 30eac1282c Reset compression session when encoding error occurs 2016-09-30 10:51:36 +08:00
小歪~~~ 77d6a5b85b Merge pull request #92 from kciter/patch-1
Add syntax highlighting
2016-09-21 16:03:16 +08:00
chenliming 73c9adeb71 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/96 2016-09-21 16:00:13 +08:00
Lee Sun-Hyoup 7dcda23bf4 Add syntax highlighting 2016-09-17 16:58:01 +09:00
chenliming aa4f259edc save video to local for mp4 2016-09-14 09:15:55 +08:00
chenliming bc5dcef3b7 修改bug 2016-09-12 15:00:26 +08:00
chenliming 782b0c3c71 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/87 2016-09-12 14:46:33 +08:00
chenliming 34a2fdd3e2 update version 2016-09-07 20:52:23 +08:00
chenliming ae128ab66b modify dealloc bug 2016-09-07 20:51:29 +08:00
chenliming cb164ed1fe fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/78#issuecomment-244348216 2016-09-02 19:43:49 +08:00
chenliming c40b99c19a fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/76 2016-09-02 17:02:20 +08:00
chenliming 2a48333a9a 默认丢帧 2016-09-01 18:44:42 +08:00
chenliming 3c0c2eecb8 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/75 2016-09-01 14:21:24 +08:00
chenliming 442f04124d fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/74 2016-09-01 14:14:04 +08:00
chenliming c03bd61f37 modify travis 2016-08-31 14:11:25 +08:00
chenliming 161c0acd68 modify readme 2016-08-31 14:10:06 +08:00
chenliming b7be132a30 update 2016-08-31 13:41:39 +08:00
chenliming d30aecc802 fix 编译问题 2016-08-31 13:34:06 +08:00
chenliming b612be76bc update... 2016-08-31 11:52:44 +08:00
chenliming a322e2aa3f fix demo 编译问题 2016-08-31 11:27:55 +08:00
chenliming b0e88e182a remove pili_rtmp 2016-08-31 11:02:47 +08:00
chenliming 3ebd933b6c update version 2016-08-31 11:02:08 +08:00
chenliming db0814ca4c update 2016-08-31 11:00:43 +08:00
chenliming 3a9e0efb73 update 2016-08-31 10:46:14 +08:00
chenliming 7bcc82a03e update.. 2016-08-31 10:36:24 +08:00
chenliming 293e021cf6 update 2016-08-31 10:26:23 +08:00
chenliming 340ab086d2 update version 2016-08-31 10:23:29 +08:00
chenliming f025f807f4 fix 编译问题 2016-08-31 10:21:23 +08:00
chenliming 90b086c7a3 Revert "update .."
This reverts commit cf56d72598.
2016-08-31 08:52:06 +08:00
chenliming cf56d72598 update .. 2016-08-31 08:49:00 +08:00
chenliming b22f61c4e2 Revert "test LFLiveKit"
This reverts commit 7d1311311c.
2016-08-30 23:31:00 +08:00
chenliming 7d1311311c test LFLiveKit 2016-08-30 23:29:06 +08:00
chenliming a508cecc32 add iPhone simulator 2016-08-30 23:08:46 +08:00
chenliming 7657d27854 add share theme 2016-08-30 20:33:44 +08:00
chenliming 7c3aae8003 fix travis 2016-08-30 17:39:58 +08:00
chenliming 8c2596c23e fix Third party library external introduction 2016-08-30 16:46:25 +08:00
chenliming 681b1cd107 Modified time stamp logic 2016-08-30 12:17:45 +08:00
chenliming 13094108e3 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/61 2016-08-30 11:01:24 +08:00
chenliming abd55c5511 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/67 2016-08-29 20:57:53 +08:00
chenliming fc52abe7bd fix code format 2016-08-29 18:05:37 +08:00
chenliming fa10e28281 Support sampling rate 16K
Modify 44.1K iphone6s sound problem
Add a local record sound(aac)
2016-08-29 17:58:58 +08:00
chenliming c624fbe78c iphone6 after audio 48000 2016-08-24 14:25:39 +08:00
小歪~~~ 19a355e697 Merge pull request #44 from zzgo/master
Add currentImage
2016-08-24 13:44:21 +08:00
chenliming 7799f0f613 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/60 2016-08-22 21:10:23 +08:00
chenliming ecf3b557cf fix memory leak 2016-08-19 16:01:17 +08:00
chenliming 58d83ed0dc modify capture sessionPreset(1280X720) bug set videoSize 360 640 2016-08-16 18:09:42 +08:00
小歪~~~ b167bda396 Merge pull request #54 from Michael-Owen/master
修复画面抖动模糊的问题
2016-08-16 18:06:05 +08:00
Michael 336a6e2432 修复画面抖动模糊的问题,presentationTimeStamp根据帧率计算 2016-08-16 17:18:29 +08:00
Michael 8acddcda90 修复画面抖动模糊的问题 2016-08-16 13:51:04 +08:00
chenliming cf2fc51fea add build sh 2016-08-15 20:25:41 +08:00
chenliming ae5f68661e update version 2016-08-12 21:06:42 +08:00
chenliming e30467dc13 fix videoSizeRespectingAspectRatio show error 2016-08-11 14:18:15 +08:00
chenliming a217868694 support External input video or audio ,set LFLiveCaptureTypeMask 2016-08-10 14:23:26 +08:00
小歪~~~ 3053a16cd3 Merge pull request #47 from toss156/master
fix #46 never mirrored rear facing camera
2016-08-09 17:21:32 +08:00
toss156 d2d7140312 update project file 2016-08-09 17:12:09 +08:00
toss156 e93549619e never mirror the rear facing camera 2016-08-09 16:51:49 +08:00
toss156 0196b1be79 Merge branch 'master' of https://github.com/LaiFengiOS/LFLiveKit
# By chenliming
# Via chenliming
* 'master' of https://github.com/LaiFengiOS/LFLiveKit:
  update waterMark postion and set outVideoSize
  Support output arbitrary size and fix iphone4  1920*720 crash

Conflicts:
	LFLiveKit/capture/LFVideoCapture.m
	LFLiveKitDemo/LFLiveKitDemo.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate
2016-08-05 15:33:27 +08:00
toss156 23ab30e668 Merge branch 'master' of https://github.com/LaiFengiOS/LFLiveKit
# By chenliming (35) and others
# Via GitHub (2) and chenliming (1)
* 'master' of https://github.com/LaiFengiOS/LFLiveKit: (37 commits)
  水印
  add watermark ..
  Update LFLiveKit.podspec
  change the AVAudioSession Category before start, or it will fail
  update..
  update
  update ..
  add a icon
  update read
  update readme
  update
  modify read
  modify read
  update travis 
  update read
  update version2.0
  add  iOS  encoder
  add carthage
  update version
  update version
  ...

Conflicts:
	LFLiveKit.xcodeproj/project.pbxproj
	LFLiveKit.xcworkspace/xcuserdata/feng.xcuserdatad/UserInterfaceState.xcuserstate
	LFLiveKit/LFLiveSession.m
	LFLiveKit/capture/LFVideoCapture.m
2016-08-05 15:27:08 +08:00
chenliming 42bd5c1f6b update waterMark postion and set outVideoSize 2016-08-05 14:06:11 +08:00
chenliming 41393ffed8 Support output arbitrary size and fix iphone4 1920*720 crash 2016-08-05 12:20:17 +08:00
zz 2b236b2a35 add currentImage
改currentImageView 为currentImage
2016-08-05 12:05:39 +08:00
zz e59699b7fd add currentImage
改currentImageView 为currentImage
2016-08-05 12:05:07 +08:00
zz e9f3c66a3b add currentImage
改currentImageView为currentImage
2016-08-05 12:04:14 +08:00
zz dc1dc18824 add currentImage
改currentImageView为currentImage
2016-08-05 12:03:15 +08:00
zz 014e73f44c add currentImage
改currentImageView为currentImage
2016-08-05 12:01:48 +08:00
zz ee7c25727b add currentImageView
获取当前视频截图
2016-08-05 11:36:45 +08:00
zz 79f0ba930b add currentImageView
获取当前视频截图
2016-08-05 11:34:37 +08:00
zz c5edbfba8e add currentImageView
获取当前视频截图
2016-08-05 11:32:47 +08:00
zz 91c689a41f add currentImageView
获取当前视频截图
2016-08-05 11:18:46 +08:00
chenliming ba48a45c0a 水印 2016-08-04 14:05:52 +08:00
chenliming af09e79e74 add watermark .. 2016-08-04 13:59:43 +08:00
小歪~~~ e4327de704 Merge pull request #38 from zhangyu528/master
Update LFLiveKit.podspec
2016-08-03 13:49:34 +08:00
Justin 9760129763 Update LFLiveKit.podspec
fix issue  #36 关于use_frameworks!的问题
2016-08-03 13:23:46 +08:00
小歪~~~ dc7f8d1d10 Merge pull request #37 from Guikunzhi/master
change the AVAudioSession Category before start, or it will fail
2016-08-03 12:18:24 +08:00
琨君 8f8bedb93d change the AVAudioSession Category before start, or it will fail 2016-08-03 10:41:55 +08:00
chenliming 9428dc2c7f update.. 2016-08-02 16:06:07 +08:00
chenliming e6c0d148ab update 2016-08-02 16:02:30 +08:00
chenliming 0ca5c18c19 update .. 2016-08-02 16:01:12 +08:00
chenliming cb98f0e70d add a icon 2016-08-02 15:55:45 +08:00
chenliming 06f1e40fba update read 2016-08-02 10:17:39 +08:00
chenliming dfbc4a51ff update readme 2016-08-01 19:46:18 +08:00
chenliming f045bb14e4 update 2016-08-01 17:26:00 +08:00
chenliming ebafc22eca modify read 2016-08-01 17:25:09 +08:00
chenliming 6e3e92a6b9 modify read 2016-08-01 17:23:14 +08:00
chenliming 26a47ffccc update travis 2016-08-01 17:12:42 +08:00
chenliming e57d3e3806 update read 2016-08-01 17:08:52 +08:00
chenliming b73bfee6ac update version2.0 2016-08-01 16:45:50 +08:00
chenliming 09398d0cb3 add iOS encoder 2016-08-01 16:42:02 +08:00
chenliming f69b586d70 add carthage 2016-08-01 16:19:36 +08:00
chenliming cfb84d31fb update version 2016-08-01 14:54:46 +08:00
chenliming 984bcb8e15 update version 2016-08-01 14:21:40 +08:00
chenliming d7164f8b76 update... 2016-08-01 13:52:51 +08:00
chenliming fb7ad31bf0 update.... 2016-08-01 13:49:59 +08:00
chenliming ec61b1f7ec update.... 2016-08-01 13:27:41 +08:00
chenliming ba1280af3a update... 2016-08-01 13:25:03 +08:00
chenliming 9e99357113 update。。。 2016-08-01 12:28:52 +08:00
chenliming 8057a3e013 update.. 2016-08-01 12:16:37 +08:00
chenliming 981b0dd2cd update... 2016-08-01 12:13:57 +08:00
chenliming d93d4b9bf5 support carthage 2016-08-01 11:50:05 +08:00
chenliming df6164fed1 modify podspec 2016-08-01 11:24:19 +08:00
chenliming ba19663059 update version 2016-08-01 11:22:16 +08:00
chenliming 0967800b23 update read 2016-08-01 11:01:55 +08:00
chenliming d0ef23d887 modify readme 2016-08-01 10:59:57 +08:00
chenliming 807d83c263 update podspec 2016-07-29 17:48:54 +08:00
chenliming 28d20814f6 update version 2016-07-29 17:43:33 +08:00
chenliming 4c385f6e89 compile question 2016-07-29 17:38:16 +08:00
chenliming 8708e04c0d modify cropSize 2016-07-29 17:08:45 +08:00
toss156 edcb2efaa0 never mirrored rear facing camera 2016-07-27 10:06:17 +08:00
chenliming e47f3154a8 modify black screen bug 2016-07-26 18:27:16 +08:00
feng 3842ff80bf Merge pull request #7 from LaiFengiOS/master
update to last version
2016-07-26 18:20:15 +08:00
toss156 d3d5f6cb24 fix mirror bug: present view is different with the stream 2016-07-26 18:15:23 +08:00
chenliming 7062cdcf7c modify bug https://github.com/LaiFengiOS/LFLiveKit/issues/11#issuecomment-235147191 2016-07-26 11:20:34 +08:00
toss156 37bfd377d6 rename h264 encode lib to avoid duplicate symbol error 2016-07-26 11:16:43 +08:00
chenliming bbe11292de modify bug https://github.com/LaiFengiOS/LFLiveKit/issues/22 2016-07-25 23:44:12 +08:00
小歪~~~ 2b51c69007 Merge pull request #21 from toss156/master
add LFH264VideoEncoder for iOS7
2016-07-25 15:25:35 +08:00
toss156 eb0edf85d2 Merge branch 'master' of https://github.com/toss156/LFLiveKit
# By chenliming (6) and bunnyirsa (1)
# Via GitHub (4) and chenliming (1)
* 'master' of https://github.com/toss156/LFLiveKit:
  update version
  add Note
  modify rtmp Continues to send after completion
  pod need 0.39,if need 1.0,please open pod file modify
  modify Weak network memory Has been increased
  修复首帧音视频不同步问题
  Modify Click the stop button to continue reconnection

Conflicts:
	LFLiveKit.xcodeproj/project.pbxproj
	LFLiveKit/LFLiveSession.m
	LFLiveKit/publish/LFStreamRTMPSocket.m
2016-07-25 15:18:57 +08:00
feng 5b097680f9 Merge pull request #6 from LaiFengiOS/master
update to last version
2016-07-25 15:01:40 +08:00
toss156 fb9ecaabad add LFH264VideoEncoder for iOS7 2016-07-25 15:00:24 +08:00
362 changed files with 15713 additions and 3467 deletions
+22 -1
View File
@@ -1,4 +1,25 @@
# infer
infer-out/
#CocoaPods
# Xcode
.DS_Store
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
*.xcworkspace
!default.xcworkspace
xcuserdata
profile
*.moved-aside
DerivedData
.idea/
# CocoaPods
Pods/
Podfile.lock
+2 -2
View File
@@ -1,7 +1,7 @@
language: objective-c
osx_image: xcode7
xcode_workspace: LFLiveKit.xcworkspace
xcode_project: FrameWork/LFLiveKit.xcodeproj
xcode_scheme: LFLiveKit
script:
- xctool -workspace LFLiveKit.xcworkspace -scheme 'LFLiveKit' -configuration Release -sdk iphonesimulator -arch i386 build
- xctool -project FrameWork/LFLiveKit.xcodeproj -scheme 'LFLiveKit' -configuration Release -sdk iphonesimulator -arch i386 build
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.9.0</string>
<string>2.4.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
@@ -0,0 +1,894 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXAggregateTarget section */
84D003751DB8FE1000560583 /* LFLiveKitFramework-universal */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 84D003761DB8FE1000560583 /* Build configuration list for PBXAggregateTarget "LFLiveKitFramework-universal" */;
buildPhases = (
84D0037B1DB8FE1C00560583 /* ShellScript */,
);
dependencies = (
84D0037A1DB8FE1800560583 /* PBXTargetDependency */,
);
name = "LFLiveKitFramework-universal";
productName = "LFLiveKitFramework-universal";
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
8495F66F1DB8F14600542124 /* LFLiveKitFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 8495F66D1DB8F14600542124 /* LFLiveKitFramework.h */; settings = {ATTRIBUTES = (Public, ); }; };
8495F6731DB8F1EE00542124 /* LFAudioCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5851D768B6E00752B56 /* LFAudioCapture.h */; };
8495F6741DB8F1EE00542124 /* LFVideoCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5871D768B6E00752B56 /* LFVideoCapture.h */; };
8495F6751DB8F1EE00542124 /* LFAVEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B58B1D768B6E00752B56 /* LFAVEncoder.h */; };
8495F6761DB8F1EE00542124 /* LFMP4Atom.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B58D1D768B6E00752B56 /* LFMP4Atom.h */; };
8495F6771DB8F1EE00542124 /* LFNALUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5901D768B6E00752B56 /* LFNALUnit.h */; };
8495F6781DB8F1EE00542124 /* LFVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5911D768B6E00752B56 /* LFVideoEncoder.h */; };
8495F6791DB8F1EE00542124 /* LFAudioEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5931D768B6E00752B56 /* LFAudioEncoding.h */; };
8495F67A1DB8F1EE00542124 /* LFH264VideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5941D768B6E00752B56 /* LFH264VideoEncoder.h */; };
8495F67B1DB8F1EE00542124 /* LFHardwareAudioEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5961D768B6E00752B56 /* LFHardwareAudioEncoder.h */; };
8495F67C1DB8F1EE00542124 /* LFHardwareVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5981D768B6E00752B56 /* LFHardwareVideoEncoder.h */; };
8495F67D1DB8F1EE00542124 /* LFVideoEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B59A1D768B6E00752B56 /* LFVideoEncoding.h */; };
8495F67E1DB8F1EE00542124 /* LFLiveAudioConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B59C1D768B6E00752B56 /* LFLiveAudioConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
8495F67F1DB8F1EE00542124 /* LFLiveVideoConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B59E1D768B6E00752B56 /* LFLiveVideoConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
8495F6801DB8F1EE00542124 /* LFGPUImageBeautyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A11D768B6E00752B56 /* LFGPUImageBeautyFilter.h */; };
8495F6811DB8F1EE00542124 /* LFGPUImageEmptyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A31D768B6E00752B56 /* LFGPUImageEmptyFilter.h */; };
8495F6831DB8F1EE00542124 /* LFLiveSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A61D768B6E00752B56 /* LFLiveSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
8495F6841DB8F1EE00542124 /* LFAudioFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A91D768B6E00752B56 /* LFAudioFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
8495F6851DB8F1EE00542124 /* LFFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5AB1D768B6E00752B56 /* LFFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
8495F6861DB8F1EE00542124 /* LFLiveDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5AD1D768B6E00752B56 /* LFLiveDebug.h */; settings = {ATTRIBUTES = (Public, ); }; };
8495F6871DB8F1EE00542124 /* LFLiveStreamInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5AF1D768B6E00752B56 /* LFLiveStreamInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
8495F6881DB8F1EE00542124 /* LFVideoFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B11D768B6E00752B56 /* LFVideoFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
8495F6891DB8F1EE00542124 /* LFStreamingBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B41D768B6E00752B56 /* LFStreamingBuffer.h */; };
8495F68A1DB8F1EE00542124 /* LFStreamRTMPSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B61D768B6E00752B56 /* LFStreamRTMPSocket.h */; };
8495F68B1DB8F1EE00542124 /* LFStreamSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B81D768B6E00752B56 /* LFStreamSocket.h */; };
8495F68C1DB8F1EE00542124 /* NSMutableArray+LFAdd.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B91D768B6E00752B56 /* NSMutableArray+LFAdd.h */; };
8495F68D1DB8F27000542124 /* LFAudioCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5861D768B6E00752B56 /* LFAudioCapture.m */; };
8495F68E1DB8F27000542124 /* LFVideoCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5881D768B6E00752B56 /* LFVideoCapture.m */; };
8495F68F1DB8F27000542124 /* LFAVEncoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B58C1D768B6E00752B56 /* LFAVEncoder.mm */; };
8495F6901DB8F27000542124 /* LFMP4Atom.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B58E1D768B6E00752B56 /* LFMP4Atom.m */; };
8495F6911DB8F27000542124 /* LFVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5921D768B6E00752B56 /* LFVideoEncoder.m */; };
8495F6921DB8F27000542124 /* LFH264VideoEncoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5951D768B6E00752B56 /* LFH264VideoEncoder.mm */; };
8495F6931DB8F27000542124 /* LFHardwareAudioEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5971D768B6E00752B56 /* LFHardwareAudioEncoder.m */; };
8495F6941DB8F27000542124 /* LFHardwareVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5991D768B6E00752B56 /* LFHardwareVideoEncoder.m */; };
8495F6951DB8F27000542124 /* LFLiveAudioConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B59D1D768B6E00752B56 /* LFLiveAudioConfiguration.m */; };
8495F6961DB8F27000542124 /* LFLiveVideoConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B59F1D768B6E00752B56 /* LFLiveVideoConfiguration.m */; };
8495F6971DB8F27000542124 /* LFGPUImageBeautyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5A21D768B6E00752B56 /* LFGPUImageBeautyFilter.m */; };
8495F6981DB8F27000542124 /* LFGPUImageEmptyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5A41D768B6E00752B56 /* LFGPUImageEmptyFilter.m */; };
8495F6991DB8F27000542124 /* LFLiveSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5A71D768B6E00752B56 /* LFLiveSession.m */; };
8495F69A1DB8F27000542124 /* LFAudioFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5AA1D768B6E00752B56 /* LFAudioFrame.m */; };
8495F69B1DB8F27000542124 /* LFFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5AC1D768B6E00752B56 /* LFFrame.m */; };
8495F69C1DB8F27000542124 /* LFLiveDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5AE1D768B6E00752B56 /* LFLiveDebug.m */; };
8495F69D1DB8F27000542124 /* LFLiveStreamInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B01D768B6E00752B56 /* LFLiveStreamInfo.m */; };
8495F69E1DB8F27000542124 /* LFVideoFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B21D768B6E00752B56 /* LFVideoFrame.m */; };
8495F69F1DB8F27000542124 /* LFStreamingBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B51D768B6E00752B56 /* LFStreamingBuffer.m */; };
8495F6A01DB8F27000542124 /* LFStreamRtmpSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B71D768B6E00752B56 /* LFStreamRtmpSocket.m */; };
8495F6A11DB8F27000542124 /* NSMutableArray+LFAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5BA1D768B6E00752B56 /* NSMutableArray+LFAdd.m */; };
84D0036F1DB8F88F00560583 /* LFNALUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B58F1D768B6E00752B56 /* LFNALUnit.cpp */; };
84D8B4BF1D757EB800752B56 /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4BE1D757EB800752B56 /* VideoToolbox.framework */; };
84D8B4C11D757EBE00752B56 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4C01D757EBE00752B56 /* AudioToolbox.framework */; };
84D8B4C31D757EC400752B56 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4C21D757EC400752B56 /* AVFoundation.framework */; };
84D8B4C51D757EC800752B56 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4C41D757EC800752B56 /* Foundation.framework */; };
84D8B4C71D757ECC00752B56 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4C61D757ECC00752B56 /* UIKit.framework */; };
84D8B5BB1D768B6E00752B56 /* LFAudioCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5851D768B6E00752B56 /* LFAudioCapture.h */; };
84D8B5BC1D768B6E00752B56 /* LFAudioCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5861D768B6E00752B56 /* LFAudioCapture.m */; };
84D8B5BD1D768B6E00752B56 /* LFVideoCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5871D768B6E00752B56 /* LFVideoCapture.h */; };
84D8B5BE1D768B6E00752B56 /* LFVideoCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5881D768B6E00752B56 /* LFVideoCapture.m */; };
84D8B5BF1D768B6E00752B56 /* LFAVEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B58B1D768B6E00752B56 /* LFAVEncoder.h */; };
84D8B5C01D768B6E00752B56 /* LFAVEncoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B58C1D768B6E00752B56 /* LFAVEncoder.mm */; };
84D8B5C11D768B6E00752B56 /* LFMP4Atom.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B58D1D768B6E00752B56 /* LFMP4Atom.h */; };
84D8B5C21D768B6E00752B56 /* LFMP4Atom.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B58E1D768B6E00752B56 /* LFMP4Atom.m */; };
84D8B5C31D768B6E00752B56 /* LFNALUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B58F1D768B6E00752B56 /* LFNALUnit.cpp */; };
84D8B5C41D768B6E00752B56 /* LFNALUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5901D768B6E00752B56 /* LFNALUnit.h */; };
84D8B5C51D768B6E00752B56 /* LFVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5911D768B6E00752B56 /* LFVideoEncoder.h */; };
84D8B5C61D768B6E00752B56 /* LFVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5921D768B6E00752B56 /* LFVideoEncoder.m */; };
84D8B5C71D768B6E00752B56 /* LFAudioEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5931D768B6E00752B56 /* LFAudioEncoding.h */; };
84D8B5C81D768B6E00752B56 /* LFH264VideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5941D768B6E00752B56 /* LFH264VideoEncoder.h */; };
84D8B5C91D768B6E00752B56 /* LFH264VideoEncoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5951D768B6E00752B56 /* LFH264VideoEncoder.mm */; };
84D8B5CA1D768B6E00752B56 /* LFHardwareAudioEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5961D768B6E00752B56 /* LFHardwareAudioEncoder.h */; };
84D8B5CB1D768B6E00752B56 /* LFHardwareAudioEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5971D768B6E00752B56 /* LFHardwareAudioEncoder.m */; };
84D8B5CC1D768B6E00752B56 /* LFHardwareVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5981D768B6E00752B56 /* LFHardwareVideoEncoder.h */; };
84D8B5CD1D768B6E00752B56 /* LFHardwareVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5991D768B6E00752B56 /* LFHardwareVideoEncoder.m */; };
84D8B5CE1D768B6E00752B56 /* LFVideoEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B59A1D768B6E00752B56 /* LFVideoEncoding.h */; };
84D8B5CF1D768B6E00752B56 /* LFLiveAudioConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B59C1D768B6E00752B56 /* LFLiveAudioConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B5D01D768B6E00752B56 /* LFLiveAudioConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B59D1D768B6E00752B56 /* LFLiveAudioConfiguration.m */; };
84D8B5D11D768B6E00752B56 /* LFLiveVideoConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B59E1D768B6E00752B56 /* LFLiveVideoConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B5D21D768B6E00752B56 /* LFLiveVideoConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B59F1D768B6E00752B56 /* LFLiveVideoConfiguration.m */; };
84D8B5D31D768B6E00752B56 /* LFGPUImageBeautyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A11D768B6E00752B56 /* LFGPUImageBeautyFilter.h */; };
84D8B5D41D768B6E00752B56 /* LFGPUImageBeautyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5A21D768B6E00752B56 /* LFGPUImageBeautyFilter.m */; };
84D8B5D51D768B6E00752B56 /* LFGPUImageEmptyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A31D768B6E00752B56 /* LFGPUImageEmptyFilter.h */; };
84D8B5D61D768B6E00752B56 /* LFGPUImageEmptyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5A41D768B6E00752B56 /* LFGPUImageEmptyFilter.m */; };
84D8B5D71D768B6E00752B56 /* LFLiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A51D768B6E00752B56 /* LFLiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B5D81D768B6E00752B56 /* LFLiveSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A61D768B6E00752B56 /* LFLiveSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B5D91D768B6E00752B56 /* LFLiveSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5A71D768B6E00752B56 /* LFLiveSession.m */; };
84D8B5DA1D768B6E00752B56 /* LFAudioFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A91D768B6E00752B56 /* LFAudioFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B5DB1D768B6E00752B56 /* LFAudioFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5AA1D768B6E00752B56 /* LFAudioFrame.m */; };
84D8B5DC1D768B6E00752B56 /* LFFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5AB1D768B6E00752B56 /* LFFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B5DD1D768B6E00752B56 /* LFFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5AC1D768B6E00752B56 /* LFFrame.m */; };
84D8B5DE1D768B6E00752B56 /* LFLiveDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5AD1D768B6E00752B56 /* LFLiveDebug.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B5DF1D768B6E00752B56 /* LFLiveDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5AE1D768B6E00752B56 /* LFLiveDebug.m */; };
84D8B5E01D768B6E00752B56 /* LFLiveStreamInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5AF1D768B6E00752B56 /* LFLiveStreamInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B5E11D768B6E00752B56 /* LFLiveStreamInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B01D768B6E00752B56 /* LFLiveStreamInfo.m */; };
84D8B5E21D768B6E00752B56 /* LFVideoFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B11D768B6E00752B56 /* LFVideoFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B5E31D768B6E00752B56 /* LFVideoFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B21D768B6E00752B56 /* LFVideoFrame.m */; };
84D8B5E41D768B6E00752B56 /* LFStreamingBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B41D768B6E00752B56 /* LFStreamingBuffer.h */; };
84D8B5E51D768B6E00752B56 /* LFStreamingBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B51D768B6E00752B56 /* LFStreamingBuffer.m */; };
84D8B5E61D768B6E00752B56 /* LFStreamRTMPSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B61D768B6E00752B56 /* LFStreamRTMPSocket.h */; };
84D8B5E71D768B6E00752B56 /* LFStreamRtmpSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B71D768B6E00752B56 /* LFStreamRtmpSocket.m */; };
84D8B5E81D768B6E00752B56 /* LFStreamSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B81D768B6E00752B56 /* LFStreamSocket.h */; };
84D8B5E91D768B6E00752B56 /* NSMutableArray+LFAdd.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B91D768B6E00752B56 /* NSMutableArray+LFAdd.h */; };
84D8B5EA1D768B6E00752B56 /* NSMutableArray+LFAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5BA1D768B6E00752B56 /* NSMutableArray+LFAdd.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
84D003791DB8FE1800560583 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84D8B3871D7574D600752B56 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8495F66A1DB8F14600542124;
remoteInfo = LFLiveKitFramework;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
8495F66B1DB8F14600542124 /* LFLiveKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LFLiveKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8495F66D1DB8F14600542124 /* LFLiveKitFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LFLiveKitFramework.h; sourceTree = "<group>"; };
8495F66E1DB8F14600542124 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
84D8B3901D7574D600752B56 /* LFLiveKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LFLiveKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
84D8B4BE1D757EB800752B56 /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; };
84D8B4C01D757EBE00752B56 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
84D8B4C21D757EC400752B56 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
84D8B4C41D757EC800752B56 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
84D8B4C61D757ECC00752B56 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
84D8B4C81D757ED100752B56 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; };
84D8B4CA1D757ED600752B56 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
84D8B5851D768B6E00752B56 /* LFAudioCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioCapture.h; sourceTree = "<group>"; };
84D8B5861D768B6E00752B56 /* LFAudioCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFAudioCapture.m; sourceTree = "<group>"; };
84D8B5871D768B6E00752B56 /* LFVideoCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoCapture.h; sourceTree = "<group>"; };
84D8B5881D768B6E00752B56 /* LFVideoCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoCapture.m; sourceTree = "<group>"; };
84D8B58B1D768B6E00752B56 /* LFAVEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAVEncoder.h; sourceTree = "<group>"; };
84D8B58C1D768B6E00752B56 /* LFAVEncoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LFAVEncoder.mm; sourceTree = "<group>"; };
84D8B58D1D768B6E00752B56 /* LFMP4Atom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFMP4Atom.h; sourceTree = "<group>"; };
84D8B58E1D768B6E00752B56 /* LFMP4Atom.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFMP4Atom.m; sourceTree = "<group>"; };
84D8B58F1D768B6E00752B56 /* LFNALUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LFNALUnit.cpp; sourceTree = "<group>"; };
84D8B5901D768B6E00752B56 /* LFNALUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFNALUnit.h; sourceTree = "<group>"; };
84D8B5911D768B6E00752B56 /* LFVideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoEncoder.h; sourceTree = "<group>"; };
84D8B5921D768B6E00752B56 /* LFVideoEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoEncoder.m; sourceTree = "<group>"; };
84D8B5931D768B6E00752B56 /* LFAudioEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioEncoding.h; sourceTree = "<group>"; };
84D8B5941D768B6E00752B56 /* LFH264VideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFH264VideoEncoder.h; sourceTree = "<group>"; };
84D8B5951D768B6E00752B56 /* LFH264VideoEncoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LFH264VideoEncoder.mm; sourceTree = "<group>"; };
84D8B5961D768B6E00752B56 /* LFHardwareAudioEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFHardwareAudioEncoder.h; sourceTree = "<group>"; };
84D8B5971D768B6E00752B56 /* LFHardwareAudioEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFHardwareAudioEncoder.m; sourceTree = "<group>"; };
84D8B5981D768B6E00752B56 /* LFHardwareVideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFHardwareVideoEncoder.h; sourceTree = "<group>"; };
84D8B5991D768B6E00752B56 /* LFHardwareVideoEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFHardwareVideoEncoder.m; sourceTree = "<group>"; };
84D8B59A1D768B6E00752B56 /* LFVideoEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoEncoding.h; sourceTree = "<group>"; };
84D8B59C1D768B6E00752B56 /* LFLiveAudioConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveAudioConfiguration.h; sourceTree = "<group>"; };
84D8B59D1D768B6E00752B56 /* LFLiveAudioConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveAudioConfiguration.m; sourceTree = "<group>"; };
84D8B59E1D768B6E00752B56 /* LFLiveVideoConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveVideoConfiguration.h; sourceTree = "<group>"; };
84D8B59F1D768B6E00752B56 /* LFLiveVideoConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveVideoConfiguration.m; sourceTree = "<group>"; };
84D8B5A11D768B6E00752B56 /* LFGPUImageBeautyFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFGPUImageBeautyFilter.h; sourceTree = "<group>"; };
84D8B5A21D768B6E00752B56 /* LFGPUImageBeautyFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFGPUImageBeautyFilter.m; sourceTree = "<group>"; };
84D8B5A31D768B6E00752B56 /* LFGPUImageEmptyFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFGPUImageEmptyFilter.h; sourceTree = "<group>"; };
84D8B5A41D768B6E00752B56 /* LFGPUImageEmptyFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFGPUImageEmptyFilter.m; sourceTree = "<group>"; };
84D8B5A51D768B6E00752B56 /* LFLiveKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveKit.h; sourceTree = "<group>"; };
84D8B5A61D768B6E00752B56 /* LFLiveSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveSession.h; sourceTree = "<group>"; };
84D8B5A71D768B6E00752B56 /* LFLiveSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveSession.m; sourceTree = "<group>"; };
84D8B5A91D768B6E00752B56 /* LFAudioFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioFrame.h; sourceTree = "<group>"; };
84D8B5AA1D768B6E00752B56 /* LFAudioFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFAudioFrame.m; sourceTree = "<group>"; };
84D8B5AB1D768B6E00752B56 /* LFFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFFrame.h; sourceTree = "<group>"; };
84D8B5AC1D768B6E00752B56 /* LFFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFFrame.m; sourceTree = "<group>"; };
84D8B5AD1D768B6E00752B56 /* LFLiveDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveDebug.h; sourceTree = "<group>"; };
84D8B5AE1D768B6E00752B56 /* LFLiveDebug.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveDebug.m; sourceTree = "<group>"; };
84D8B5AF1D768B6E00752B56 /* LFLiveStreamInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveStreamInfo.h; sourceTree = "<group>"; };
84D8B5B01D768B6E00752B56 /* LFLiveStreamInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveStreamInfo.m; sourceTree = "<group>"; };
84D8B5B11D768B6E00752B56 /* LFVideoFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoFrame.h; sourceTree = "<group>"; };
84D8B5B21D768B6E00752B56 /* LFVideoFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoFrame.m; sourceTree = "<group>"; };
84D8B5B41D768B6E00752B56 /* LFStreamingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFStreamingBuffer.h; sourceTree = "<group>"; };
84D8B5B51D768B6E00752B56 /* LFStreamingBuffer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFStreamingBuffer.m; sourceTree = "<group>"; };
84D8B5B61D768B6E00752B56 /* LFStreamRTMPSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFStreamRTMPSocket.h; sourceTree = "<group>"; };
84D8B5B71D768B6E00752B56 /* LFStreamRtmpSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFStreamRtmpSocket.m; sourceTree = "<group>"; };
84D8B5B81D768B6E00752B56 /* LFStreamSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFStreamSocket.h; sourceTree = "<group>"; };
84D8B5B91D768B6E00752B56 /* NSMutableArray+LFAdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+LFAdd.h"; sourceTree = "<group>"; };
84D8B5BA1D768B6E00752B56 /* NSMutableArray+LFAdd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+LFAdd.m"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8495F6671DB8F14600542124 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
84D8B38C1D7574D600752B56 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
84D8B4C71D757ECC00752B56 /* UIKit.framework in Frameworks */,
84D8B4C51D757EC800752B56 /* Foundation.framework in Frameworks */,
84D8B4C31D757EC400752B56 /* AVFoundation.framework in Frameworks */,
84D8B4C11D757EBE00752B56 /* AudioToolbox.framework in Frameworks */,
84D8B4BF1D757EB800752B56 /* VideoToolbox.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
8495F66C1DB8F14600542124 /* LFLiveKitFramework */ = {
isa = PBXGroup;
children = (
8495F66D1DB8F14600542124 /* LFLiveKitFramework.h */,
8495F66E1DB8F14600542124 /* Info.plist */,
);
path = LFLiveKitFramework;
sourceTree = "<group>";
};
84D8B3861D7574D600752B56 = {
isa = PBXGroup;
children = (
84D8B5831D768B6E00752B56 /* LFLiveKit */,
84D8B4CA1D757ED600752B56 /* libz.tbd */,
84D8B4C81D757ED100752B56 /* libstdc++.tbd */,
84D8B4C61D757ECC00752B56 /* UIKit.framework */,
84D8B4C41D757EC800752B56 /* Foundation.framework */,
84D8B4C21D757EC400752B56 /* AVFoundation.framework */,
84D8B4C01D757EBE00752B56 /* AudioToolbox.framework */,
84D8B4BE1D757EB800752B56 /* VideoToolbox.framework */,
8495F66C1DB8F14600542124 /* LFLiveKitFramework */,
84D8B3911D7574D600752B56 /* Products */,
9ABACAFFC334034AA0115426 /* Frameworks */,
);
sourceTree = "<group>";
};
84D8B3911D7574D600752B56 /* Products */ = {
isa = PBXGroup;
children = (
84D8B3901D7574D600752B56 /* LFLiveKit.framework */,
8495F66B1DB8F14600542124 /* LFLiveKit.framework */,
);
name = Products;
sourceTree = "<group>";
};
84D8B5831D768B6E00752B56 /* LFLiveKit */ = {
isa = PBXGroup;
children = (
84D8B5841D768B6E00752B56 /* capture */,
84D8B5891D768B6E00752B56 /* coder */,
84D8B59B1D768B6E00752B56 /* configuration */,
84D8B5A01D768B6E00752B56 /* filter */,
84D8B5A51D768B6E00752B56 /* LFLiveKit.h */,
84D8B5A61D768B6E00752B56 /* LFLiveSession.h */,
84D8B5A71D768B6E00752B56 /* LFLiveSession.m */,
84D8B5A81D768B6E00752B56 /* objects */,
84D8B5B31D768B6E00752B56 /* publish */,
);
name = LFLiveKit;
path = ../LFLiveKit;
sourceTree = "<group>";
};
84D8B5841D768B6E00752B56 /* capture */ = {
isa = PBXGroup;
children = (
84D8B5851D768B6E00752B56 /* LFAudioCapture.h */,
84D8B5861D768B6E00752B56 /* LFAudioCapture.m */,
84D8B5871D768B6E00752B56 /* LFVideoCapture.h */,
84D8B5881D768B6E00752B56 /* LFVideoCapture.m */,
);
path = capture;
sourceTree = "<group>";
};
84D8B5891D768B6E00752B56 /* coder */ = {
isa = PBXGroup;
children = (
84D8B58A1D768B6E00752B56 /* H264 */,
84D8B5931D768B6E00752B56 /* LFAudioEncoding.h */,
84D8B5941D768B6E00752B56 /* LFH264VideoEncoder.h */,
84D8B5951D768B6E00752B56 /* LFH264VideoEncoder.mm */,
84D8B5961D768B6E00752B56 /* LFHardwareAudioEncoder.h */,
84D8B5971D768B6E00752B56 /* LFHardwareAudioEncoder.m */,
84D8B5981D768B6E00752B56 /* LFHardwareVideoEncoder.h */,
84D8B5991D768B6E00752B56 /* LFHardwareVideoEncoder.m */,
84D8B59A1D768B6E00752B56 /* LFVideoEncoding.h */,
);
path = coder;
sourceTree = "<group>";
};
84D8B58A1D768B6E00752B56 /* H264 */ = {
isa = PBXGroup;
children = (
84D8B58B1D768B6E00752B56 /* LFAVEncoder.h */,
84D8B58C1D768B6E00752B56 /* LFAVEncoder.mm */,
84D8B58D1D768B6E00752B56 /* LFMP4Atom.h */,
84D8B58E1D768B6E00752B56 /* LFMP4Atom.m */,
84D8B58F1D768B6E00752B56 /* LFNALUnit.cpp */,
84D8B5901D768B6E00752B56 /* LFNALUnit.h */,
84D8B5911D768B6E00752B56 /* LFVideoEncoder.h */,
84D8B5921D768B6E00752B56 /* LFVideoEncoder.m */,
);
path = H264;
sourceTree = "<group>";
};
84D8B59B1D768B6E00752B56 /* configuration */ = {
isa = PBXGroup;
children = (
84D8B59C1D768B6E00752B56 /* LFLiveAudioConfiguration.h */,
84D8B59D1D768B6E00752B56 /* LFLiveAudioConfiguration.m */,
84D8B59E1D768B6E00752B56 /* LFLiveVideoConfiguration.h */,
84D8B59F1D768B6E00752B56 /* LFLiveVideoConfiguration.m */,
);
path = configuration;
sourceTree = "<group>";
};
84D8B5A01D768B6E00752B56 /* filter */ = {
isa = PBXGroup;
children = (
84D8B5A11D768B6E00752B56 /* LFGPUImageBeautyFilter.h */,
84D8B5A21D768B6E00752B56 /* LFGPUImageBeautyFilter.m */,
84D8B5A31D768B6E00752B56 /* LFGPUImageEmptyFilter.h */,
84D8B5A41D768B6E00752B56 /* LFGPUImageEmptyFilter.m */,
);
path = filter;
sourceTree = "<group>";
};
84D8B5A81D768B6E00752B56 /* objects */ = {
isa = PBXGroup;
children = (
84D8B5A91D768B6E00752B56 /* LFAudioFrame.h */,
84D8B5AA1D768B6E00752B56 /* LFAudioFrame.m */,
84D8B5AB1D768B6E00752B56 /* LFFrame.h */,
84D8B5AC1D768B6E00752B56 /* LFFrame.m */,
84D8B5AD1D768B6E00752B56 /* LFLiveDebug.h */,
84D8B5AE1D768B6E00752B56 /* LFLiveDebug.m */,
84D8B5AF1D768B6E00752B56 /* LFLiveStreamInfo.h */,
84D8B5B01D768B6E00752B56 /* LFLiveStreamInfo.m */,
84D8B5B11D768B6E00752B56 /* LFVideoFrame.h */,
84D8B5B21D768B6E00752B56 /* LFVideoFrame.m */,
);
path = objects;
sourceTree = "<group>";
};
84D8B5B31D768B6E00752B56 /* publish */ = {
isa = PBXGroup;
children = (
84D8B5B41D768B6E00752B56 /* LFStreamingBuffer.h */,
84D8B5B51D768B6E00752B56 /* LFStreamingBuffer.m */,
84D8B5B61D768B6E00752B56 /* LFStreamRTMPSocket.h */,
84D8B5B71D768B6E00752B56 /* LFStreamRtmpSocket.m */,
84D8B5B81D768B6E00752B56 /* LFStreamSocket.h */,
84D8B5B91D768B6E00752B56 /* NSMutableArray+LFAdd.h */,
84D8B5BA1D768B6E00752B56 /* NSMutableArray+LFAdd.m */,
);
path = publish;
sourceTree = "<group>";
};
9ABACAFFC334034AA0115426 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
8495F6681DB8F14600542124 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
8495F6861DB8F1EE00542124 /* LFLiveDebug.h in Headers */,
8495F6881DB8F1EE00542124 /* LFVideoFrame.h in Headers */,
8495F6871DB8F1EE00542124 /* LFLiveStreamInfo.h in Headers */,
8495F6851DB8F1EE00542124 /* LFFrame.h in Headers */,
8495F6841DB8F1EE00542124 /* LFAudioFrame.h in Headers */,
8495F67F1DB8F1EE00542124 /* LFLiveVideoConfiguration.h in Headers */,
8495F67E1DB8F1EE00542124 /* LFLiveAudioConfiguration.h in Headers */,
8495F6831DB8F1EE00542124 /* LFLiveSession.h in Headers */,
8495F66F1DB8F14600542124 /* LFLiveKitFramework.h in Headers */,
8495F6731DB8F1EE00542124 /* LFAudioCapture.h in Headers */,
8495F6741DB8F1EE00542124 /* LFVideoCapture.h in Headers */,
8495F6751DB8F1EE00542124 /* LFAVEncoder.h in Headers */,
8495F6761DB8F1EE00542124 /* LFMP4Atom.h in Headers */,
8495F6771DB8F1EE00542124 /* LFNALUnit.h in Headers */,
8495F6781DB8F1EE00542124 /* LFVideoEncoder.h in Headers */,
8495F6791DB8F1EE00542124 /* LFAudioEncoding.h in Headers */,
8495F67A1DB8F1EE00542124 /* LFH264VideoEncoder.h in Headers */,
8495F67B1DB8F1EE00542124 /* LFHardwareAudioEncoder.h in Headers */,
8495F67C1DB8F1EE00542124 /* LFHardwareVideoEncoder.h in Headers */,
8495F67D1DB8F1EE00542124 /* LFVideoEncoding.h in Headers */,
8495F6801DB8F1EE00542124 /* LFGPUImageBeautyFilter.h in Headers */,
8495F6811DB8F1EE00542124 /* LFGPUImageEmptyFilter.h in Headers */,
8495F6891DB8F1EE00542124 /* LFStreamingBuffer.h in Headers */,
8495F68A1DB8F1EE00542124 /* LFStreamRTMPSocket.h in Headers */,
8495F68B1DB8F1EE00542124 /* LFStreamSocket.h in Headers */,
8495F68C1DB8F1EE00542124 /* NSMutableArray+LFAdd.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
84D8B38D1D7574D600752B56 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
84D8B5DE1D768B6E00752B56 /* LFLiveDebug.h in Headers */,
84D8B5CF1D768B6E00752B56 /* LFLiveAudioConfiguration.h in Headers */,
84D8B5DA1D768B6E00752B56 /* LFAudioFrame.h in Headers */,
84D8B5E01D768B6E00752B56 /* LFLiveStreamInfo.h in Headers */,
84D8B5D11D768B6E00752B56 /* LFLiveVideoConfiguration.h in Headers */,
84D8B5DC1D768B6E00752B56 /* LFFrame.h in Headers */,
84D8B5D71D768B6E00752B56 /* LFLiveKit.h in Headers */,
84D8B5D81D768B6E00752B56 /* LFLiveSession.h in Headers */,
84D8B5E21D768B6E00752B56 /* LFVideoFrame.h in Headers */,
84D8B5BB1D768B6E00752B56 /* LFAudioCapture.h in Headers */,
84D8B5E61D768B6E00752B56 /* LFStreamRTMPSocket.h in Headers */,
84D8B5C11D768B6E00752B56 /* LFMP4Atom.h in Headers */,
84D8B5D31D768B6E00752B56 /* LFGPUImageBeautyFilter.h in Headers */,
84D8B5BF1D768B6E00752B56 /* LFAVEncoder.h in Headers */,
84D8B5C51D768B6E00752B56 /* LFVideoEncoder.h in Headers */,
84D8B5D51D768B6E00752B56 /* LFGPUImageEmptyFilter.h in Headers */,
84D8B5C71D768B6E00752B56 /* LFAudioEncoding.h in Headers */,
84D8B5E91D768B6E00752B56 /* NSMutableArray+LFAdd.h in Headers */,
84D8B5CC1D768B6E00752B56 /* LFHardwareVideoEncoder.h in Headers */,
84D8B5BD1D768B6E00752B56 /* LFVideoCapture.h in Headers */,
84D8B5E81D768B6E00752B56 /* LFStreamSocket.h in Headers */,
84D8B5C41D768B6E00752B56 /* LFNALUnit.h in Headers */,
84D8B5CA1D768B6E00752B56 /* LFHardwareAudioEncoder.h in Headers */,
84D8B5CE1D768B6E00752B56 /* LFVideoEncoding.h in Headers */,
84D8B5E41D768B6E00752B56 /* LFStreamingBuffer.h in Headers */,
84D8B5C81D768B6E00752B56 /* LFH264VideoEncoder.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
8495F66A1DB8F14600542124 /* LFLiveKitFramework */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8495F6701DB8F14600542124 /* Build configuration list for PBXNativeTarget "LFLiveKitFramework" */;
buildPhases = (
8495F6661DB8F14600542124 /* Sources */,
8495F6671DB8F14600542124 /* Frameworks */,
8495F6681DB8F14600542124 /* Headers */,
8495F6691DB8F14600542124 /* Resources */,
84D0037D1DB9023F00560583 /* ShellScript */,
);
buildRules = (
);
dependencies = (
);
name = LFLiveKitFramework;
productName = LFLiveKitFramework;
productReference = 8495F66B1DB8F14600542124 /* LFLiveKit.framework */;
productType = "com.apple.product-type.framework";
};
84D8B38F1D7574D600752B56 /* LFLiveKit */ = {
isa = PBXNativeTarget;
buildConfigurationList = 84D8B3981D7574D600752B56 /* Build configuration list for PBXNativeTarget "LFLiveKit" */;
buildPhases = (
84D8B38B1D7574D600752B56 /* Sources */,
84D8B38C1D7574D600752B56 /* Frameworks */,
84D8B38D1D7574D600752B56 /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = LFLiveKit;
productName = LFLiveKit;
productReference = 84D8B3901D7574D600752B56 /* LFLiveKit.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
84D8B3871D7574D600752B56 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = admin;
TargetAttributes = {
8495F66A1DB8F14600542124 = {
CreatedOnToolsVersion = 8.0;
ProvisioningStyle = Automatic;
};
84D003751DB8FE1000560583 = {
CreatedOnToolsVersion = 8.0;
DevelopmentTeam = G497YX6CBT;
ProvisioningStyle = Automatic;
};
84D8B38F1D7574D600752B56 = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = 84D8B38A1D7574D600752B56 /* Build configuration list for PBXProject "LFLiveKit" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 84D8B3861D7574D600752B56;
productRefGroup = 84D8B3911D7574D600752B56 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
84D8B38F1D7574D600752B56 /* LFLiveKit */,
8495F66A1DB8F14600542124 /* LFLiveKitFramework */,
84D003751DB8FE1000560583 /* LFLiveKitFramework-universal */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8495F6691DB8F14600542124 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
84D0037B1DB8FE1C00560583 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "../scripts/build-universal-framework.sh\n";
};
84D0037D1DB9023F00560583 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "echo \"${env}\"";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8495F6661DB8F14600542124 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
84D0036F1DB8F88F00560583 /* LFNALUnit.cpp in Sources */,
8495F68D1DB8F27000542124 /* LFAudioCapture.m in Sources */,
8495F68E1DB8F27000542124 /* LFVideoCapture.m in Sources */,
8495F68F1DB8F27000542124 /* LFAVEncoder.mm in Sources */,
8495F6901DB8F27000542124 /* LFMP4Atom.m in Sources */,
8495F6911DB8F27000542124 /* LFVideoEncoder.m in Sources */,
8495F6921DB8F27000542124 /* LFH264VideoEncoder.mm in Sources */,
8495F6931DB8F27000542124 /* LFHardwareAudioEncoder.m in Sources */,
8495F6941DB8F27000542124 /* LFHardwareVideoEncoder.m in Sources */,
8495F6951DB8F27000542124 /* LFLiveAudioConfiguration.m in Sources */,
8495F6961DB8F27000542124 /* LFLiveVideoConfiguration.m in Sources */,
8495F6971DB8F27000542124 /* LFGPUImageBeautyFilter.m in Sources */,
8495F6981DB8F27000542124 /* LFGPUImageEmptyFilter.m in Sources */,
8495F6991DB8F27000542124 /* LFLiveSession.m in Sources */,
8495F69A1DB8F27000542124 /* LFAudioFrame.m in Sources */,
8495F69B1DB8F27000542124 /* LFFrame.m in Sources */,
8495F69C1DB8F27000542124 /* LFLiveDebug.m in Sources */,
8495F69D1DB8F27000542124 /* LFLiveStreamInfo.m in Sources */,
8495F69E1DB8F27000542124 /* LFVideoFrame.m in Sources */,
8495F69F1DB8F27000542124 /* LFStreamingBuffer.m in Sources */,
8495F6A01DB8F27000542124 /* LFStreamRtmpSocket.m in Sources */,
8495F6A11DB8F27000542124 /* NSMutableArray+LFAdd.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
84D8B38B1D7574D600752B56 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
84D8B5D41D768B6E00752B56 /* LFGPUImageBeautyFilter.m in Sources */,
84D8B5DD1D768B6E00752B56 /* LFFrame.m in Sources */,
84D8B5DF1D768B6E00752B56 /* LFLiveDebug.m in Sources */,
84D8B5BE1D768B6E00752B56 /* LFVideoCapture.m in Sources */,
84D8B5DB1D768B6E00752B56 /* LFAudioFrame.m in Sources */,
84D8B5E11D768B6E00752B56 /* LFLiveStreamInfo.m in Sources */,
84D8B5C31D768B6E00752B56 /* LFNALUnit.cpp in Sources */,
84D8B5C01D768B6E00752B56 /* LFAVEncoder.mm in Sources */,
84D8B5C21D768B6E00752B56 /* LFMP4Atom.m in Sources */,
84D8B5D21D768B6E00752B56 /* LFLiveVideoConfiguration.m in Sources */,
84D8B5C61D768B6E00752B56 /* LFVideoEncoder.m in Sources */,
84D8B5D61D768B6E00752B56 /* LFGPUImageEmptyFilter.m in Sources */,
84D8B5D91D768B6E00752B56 /* LFLiveSession.m in Sources */,
84D8B5E71D768B6E00752B56 /* LFStreamRtmpSocket.m in Sources */,
84D8B5D01D768B6E00752B56 /* LFLiveAudioConfiguration.m in Sources */,
84D8B5CB1D768B6E00752B56 /* LFHardwareAudioEncoder.m in Sources */,
84D8B5C91D768B6E00752B56 /* LFH264VideoEncoder.mm in Sources */,
84D8B5E51D768B6E00752B56 /* LFStreamingBuffer.m in Sources */,
84D8B5CD1D768B6E00752B56 /* LFHardwareVideoEncoder.m in Sources */,
84D8B5E31D768B6E00752B56 /* LFVideoFrame.m in Sources */,
84D8B5BC1D768B6E00752B56 /* LFAudioCapture.m in Sources */,
84D8B5EA1D768B6E00752B56 /* NSMutableArray+LFAdd.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
84D0037A1DB8FE1800560583 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8495F66A1DB8F14600542124 /* LFLiveKitFramework */;
targetProxy = 84D003791DB8FE1800560583 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
8495F6711DB8F14600542124 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"\"$(SRCROOT)/../samples/LFLiveKitFrameworkDemo/vendors/GPUImage.framework\"",
"\"$(SRCROOT)/../samples/LFLiveKitFrameworkDemo/vendors/pili-librtmp.framework\"",
);
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../samples/LFLiveKitFrameworkDemo/vendors/GPUImage.framework/Headers\"",
"\"$(SRCROOT)/../samples/LFLiveKitFrameworkDemo/vendors/pili-librtmp.framework/Headers\"",
);
INFOPLIST_FILE = LFLiveKitFramework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKit;
PRODUCT_NAME = LFLiveKit;
SKIP_INSTALL = YES;
};
name = Debug;
};
8495F6721DB8F14600542124 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"\"$(SRCROOT)/../samples/LFLiveKitFrameworkDemo/vendors/GPUImage.framework\"",
"\"$(SRCROOT)/../samples/LFLiveKitFrameworkDemo/vendors/pili-librtmp.framework\"",
);
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../samples/LFLiveKitFrameworkDemo/vendors/GPUImage.framework/Headers\"",
"\"$(SRCROOT)/../samples/LFLiveKitFrameworkDemo/vendors/pili-librtmp.framework/Headers\"",
);
INFOPLIST_FILE = LFLiveKitFramework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKit;
PRODUCT_NAME = LFLiveKit;
SKIP_INSTALL = YES;
};
name = Release;
};
84D003771DB8FE1000560583 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEVELOPMENT_TEAM = G497YX6CBT;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
84D003781DB8FE1000560583 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEVELOPMENT_TEAM = G497YX6CBT;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
84D8B3961D7574D600752B56 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
84D8B3971D7574D600752B56 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
84D8B3991D7574D600752B56 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
HEADER_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../samples/LFLiveKitDemo/Pods\"/**",
);
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
MACH_O_TYPE = staticlib;
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
84D8B39A1D7574D600752B56 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
HEADER_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../samples/LFLiveKitDemo/Pods\"/**",
);
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
MACH_O_TYPE = staticlib;
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
8495F6701DB8F14600542124 /* Build configuration list for PBXNativeTarget "LFLiveKitFramework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8495F6711DB8F14600542124 /* Debug */,
8495F6721DB8F14600542124 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
84D003761DB8FE1000560583 /* Build configuration list for PBXAggregateTarget "LFLiveKitFramework-universal" */ = {
isa = XCConfigurationList;
buildConfigurations = (
84D003771DB8FE1000560583 /* Debug */,
84D003781DB8FE1000560583 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
84D8B38A1D7574D600752B56 /* Build configuration list for PBXProject "LFLiveKit" */ = {
isa = XCConfigurationList;
buildConfigurations = (
84D8B3961D7574D600752B56 /* Debug */,
84D8B3971D7574D600752B56 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
84D8B3981D7574D600752B56 /* Build configuration list for PBXNativeTarget "LFLiveKit" */ = {
isa = XCConfigurationList;
buildConfigurations = (
84D8B3991D7574D600752B56 /* Debug */,
84D8B39A1D7574D600752B56 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 84D8B3871D7574D600752B56 /* Project object */;
}
@@ -14,10 +14,10 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B2D23E791D348F3D00B34CA8"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
BlueprintIdentifier = "84D8B38F1D7574D600752B56"
BuildableName = "LFLiveKit.framework"
BlueprintName = "LFLiveKit"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -29,20 +29,11 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B2D23E791D348F3D00B34CA8"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@@ -51,16 +42,15 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B2D23E791D348F3D00B34CA8"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
BlueprintIdentifier = "84D8B38F1D7574D600752B56"
BuildableName = "LFLiveKit.framework"
BlueprintName = "LFLiveKit"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
@@ -70,16 +60,15 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B2D23E791D348F3D00B34CA8"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
BlueprintIdentifier = "84D8B38F1D7574D600752B56"
BuildableName = "LFLiveKit.framework"
BlueprintName = "LFLiveKit"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
@@ -13,12 +13,12 @@
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<string>2.4.3</string>
<key>CFBundleVersion</key>
<string>1</string>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
@@ -0,0 +1,26 @@
//
// LFLiveKitFramework.h
// LFLiveKitFramework
//
// Created by admin on 2016/10/20.
// Copyright © 2016年 admin. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for LFLiveKitFramework.
FOUNDATION_EXPORT double LFLiveKitFrameworkVersionNumber;
//! Project version string for LFLiveKitFramework.
FOUNDATION_EXPORT const unsigned char LFLiveKitFrameworkVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <LFLiveKitFramework/PublicHeader.h>
#import <LFLiveKit/LFLiveSession.h>
#import <LFLiveKit/LFLiveAudioConfiguration.h>
#import <LFLiveKit/LFLiveVideoConfiguration.h>
#import <LFLiveKit/LFAudioFrame.h>
#import <LFLiveKit/LFFrame.h>
#import <LFLiveKit/LFLiveStreamInfo.h>
#import <LFLiveKit/LFVideoFrame.h>
#import <LFLiveKit/LFLiveDebug.h>
+8 -11
View File
@@ -2,24 +2,21 @@
Pod::Spec.new do |s|
s.name = "LFLiveKit"
s.version = "1.9.0"
s.version = "2.4.3"
s.summary = "LaiFeng ios Live. LFLiveKit."
s.homepage = "https://github.com/chenliming777"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "chenliming" => "chenliming777@qq.com" }
s.platform = :ios, "8.0"
s.ios.deployment_target = "8.0"
s.platform = :ios, "7.0"
s.ios.deployment_target = "7.0"
s.source = { :git => "https://github.com/LaiFengiOS/LFLiveKit.git", :tag => "#{s.version}" }
s.source_files = "LFLiveKit/**/*.{h,m}"
s.public_header_files = "LFLiveKit/**/*.h"
s.source_files = "LFLiveKit/**/*.{h,m,mm,cpp,c}"
s.public_header_files = ['LFLiveKit/*.h', 'LFLiveKit/objects/*.h', 'LFLiveKit/configuration/*.h']
s.frameworks = "VideoToolbox", "AudioToolbox","AVFoundation","Foundation","UIKit"
s.library = "z"
s.libraries = "c++", "z"
s.requires_arc = true
s.dependency 'LMGPUImage', '~> 0.1.9'
s.dependency "pili-librtmp", "~> 1.0.3"
s.dependency "YYDispatchQueuePool"
s.dependency 'GPUImage'
s.dependency 'pili-librtmp', '1.0.3.1'
end
-715
View File
@@ -1,715 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
84001F8E1D0015D10026C63F /* LFLiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001F8D1D0015D10026C63F /* LFLiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
84001F951D0015D10026C63F /* LFLiveKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84001F8A1D0015D10026C63F /* LFLiveKit.framework */; };
84001F9A1D0015D10026C63F /* LFLiveKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001F991D0015D10026C63F /* LFLiveKitTests.m */; };
84001FD11D0016380026C63F /* LFAudioCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FA51D0016380026C63F /* LFAudioCapture.h */; };
84001FD21D0016380026C63F /* LFAudioCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FA61D0016380026C63F /* LFAudioCapture.m */; };
84001FD31D0016380026C63F /* LFVideoCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FA71D0016380026C63F /* LFVideoCapture.h */; };
84001FD41D0016380026C63F /* LFVideoCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FA81D0016380026C63F /* LFVideoCapture.m */; };
84001FD51D0016380026C63F /* LFAudioEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FAA1D0016380026C63F /* LFAudioEncoding.h */; };
84001FD61D0016380026C63F /* LFHardwareAudioEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FAB1D0016380026C63F /* LFHardwareAudioEncoder.h */; };
84001FD71D0016380026C63F /* LFHardwareAudioEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FAC1D0016380026C63F /* LFHardwareAudioEncoder.m */; };
84001FD81D0016380026C63F /* LFHardwareVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FAD1D0016380026C63F /* LFHardwareVideoEncoder.h */; };
84001FD91D0016380026C63F /* LFHardwareVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FAE1D0016380026C63F /* LFHardwareVideoEncoder.m */; };
84001FDA1D0016380026C63F /* LFVideoEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FAF1D0016380026C63F /* LFVideoEncoding.h */; };
84001FDB1D0016380026C63F /* LFLiveAudioConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FB11D0016380026C63F /* LFLiveAudioConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
84001FDC1D0016380026C63F /* LFLiveAudioConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FB21D0016380026C63F /* LFLiveAudioConfiguration.m */; };
84001FDD1D0016380026C63F /* LFLiveVideoConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FB31D0016380026C63F /* LFLiveVideoConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
84001FDE1D0016380026C63F /* LFLiveVideoConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FB41D0016380026C63F /* LFLiveVideoConfiguration.m */; };
84001FDF1D0016380026C63F /* LFGPUImageBeautyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FB61D0016380026C63F /* LFGPUImageBeautyFilter.h */; };
84001FE01D0016380026C63F /* LFGPUImageBeautyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FB71D0016380026C63F /* LFGPUImageBeautyFilter.m */; };
84001FE11D0016380026C63F /* LFGPUImageEmptyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FB81D0016380026C63F /* LFGPUImageEmptyFilter.h */; };
84001FE21D0016380026C63F /* LFGPUImageEmptyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FB91D0016380026C63F /* LFGPUImageEmptyFilter.m */; };
84001FE31D0016380026C63F /* LFLiveSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FBA1D0016380026C63F /* LFLiveSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
84001FE41D0016380026C63F /* LFLiveSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FBB1D0016380026C63F /* LFLiveSession.m */; };
84001FE51D0016380026C63F /* LFAudioFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FBD1D0016380026C63F /* LFAudioFrame.h */; };
84001FE61D0016380026C63F /* LFAudioFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FBE1D0016380026C63F /* LFAudioFrame.m */; };
84001FE71D0016380026C63F /* LFFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FBF1D0016380026C63F /* LFFrame.h */; };
84001FE81D0016380026C63F /* LFFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FC01D0016380026C63F /* LFFrame.m */; };
84001FE91D0016380026C63F /* LFLiveDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FC11D0016380026C63F /* LFLiveDebug.h */; settings = {ATTRIBUTES = (Public, ); }; };
84001FEA1D0016380026C63F /* LFLiveDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FC21D0016380026C63F /* LFLiveDebug.m */; };
84001FEB1D0016380026C63F /* LFLiveStreamInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FC31D0016380026C63F /* LFLiveStreamInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
84001FEC1D0016380026C63F /* LFLiveStreamInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FC41D0016380026C63F /* LFLiveStreamInfo.m */; };
84001FED1D0016380026C63F /* LFVideoFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84001FC51D0016380026C63F /* LFVideoFrame.h */; };
84001FEE1D0016380026C63F /* LFVideoFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84001FC61D0016380026C63F /* LFVideoFrame.m */; };
84001FF71D0017590026C63F /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84001FF61D0017590026C63F /* AVFoundation.framework */; };
84001FF91D00175D0026C63F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84001FF81D00175D0026C63F /* Foundation.framework */; };
84001FFB1D0017630026C63F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84001FFA1D0017630026C63F /* UIKit.framework */; };
84001FFD1D0017680026C63F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84001FFC1D0017680026C63F /* AudioToolbox.framework */; };
84001FFF1D00176C0026C63F /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84001FFE1D00176C0026C63F /* VideoToolbox.framework */; };
840020011D0017850026C63F /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 840020001D0017850026C63F /* libz.tbd */; };
AD7F89B4621A7EFEBEA72D49 /* libPods-LFLiveKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B8CB02D2A92EA1F5A262F154 /* libPods-LFLiveKit.a */; };
B289F1DB1D3DE77F00D9C7A5 /* LFStreamingBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B289F1D41D3DE77F00D9C7A5 /* LFStreamingBuffer.h */; };
B289F1DC1D3DE77F00D9C7A5 /* LFStreamingBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = B289F1D51D3DE77F00D9C7A5 /* LFStreamingBuffer.m */; };
B289F1DD1D3DE77F00D9C7A5 /* LFStreamRtmpSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = B289F1D61D3DE77F00D9C7A5 /* LFStreamRtmpSocket.h */; };
B289F1DE1D3DE77F00D9C7A5 /* LFStreamRtmpSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = B289F1D71D3DE77F00D9C7A5 /* LFStreamRtmpSocket.m */; };
B289F1DF1D3DE77F00D9C7A5 /* LFStreamSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = B289F1D81D3DE77F00D9C7A5 /* LFStreamSocket.h */; };
B289F1E01D3DE77F00D9C7A5 /* NSMutableArray+LFAdd.h in Headers */ = {isa = PBXBuildFile; fileRef = B289F1D91D3DE77F00D9C7A5 /* NSMutableArray+LFAdd.h */; };
B289F1E11D3DE77F00D9C7A5 /* NSMutableArray+LFAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = B289F1DA1D3DE77F00D9C7A5 /* NSMutableArray+LFAdd.m */; };
BE55DA79155500CDEF87FB5C /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5758EB2A15DAA132D8BF380 /* libPods.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
84001F961D0015D10026C63F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84001F811D0015D10026C63F /* Project object */;
proxyType = 1;
remoteGlobalIDString = 84001F891D0015D10026C63F;
remoteInfo = LFLiveKit;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
84001F8A1D0015D10026C63F /* LFLiveKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LFLiveKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
84001F8D1D0015D10026C63F /* LFLiveKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LFLiveKit.h; sourceTree = "<group>"; };
84001F8F1D0015D10026C63F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
84001F941D0015D10026C63F /* LFLiveKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LFLiveKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
84001F991D0015D10026C63F /* LFLiveKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LFLiveKitTests.m; sourceTree = "<group>"; };
84001F9B1D0015D10026C63F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
84001FA51D0016380026C63F /* LFAudioCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioCapture.h; sourceTree = "<group>"; };
84001FA61D0016380026C63F /* LFAudioCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFAudioCapture.m; sourceTree = "<group>"; };
84001FA71D0016380026C63F /* LFVideoCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoCapture.h; sourceTree = "<group>"; };
84001FA81D0016380026C63F /* LFVideoCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoCapture.m; sourceTree = "<group>"; };
84001FAA1D0016380026C63F /* LFAudioEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioEncoding.h; sourceTree = "<group>"; };
84001FAB1D0016380026C63F /* LFHardwareAudioEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFHardwareAudioEncoder.h; sourceTree = "<group>"; };
84001FAC1D0016380026C63F /* LFHardwareAudioEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFHardwareAudioEncoder.m; sourceTree = "<group>"; };
84001FAD1D0016380026C63F /* LFHardwareVideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFHardwareVideoEncoder.h; sourceTree = "<group>"; };
84001FAE1D0016380026C63F /* LFHardwareVideoEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFHardwareVideoEncoder.m; sourceTree = "<group>"; };
84001FAF1D0016380026C63F /* LFVideoEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoEncoding.h; sourceTree = "<group>"; };
84001FB11D0016380026C63F /* LFLiveAudioConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveAudioConfiguration.h; sourceTree = "<group>"; };
84001FB21D0016380026C63F /* LFLiveAudioConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveAudioConfiguration.m; sourceTree = "<group>"; };
84001FB31D0016380026C63F /* LFLiveVideoConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveVideoConfiguration.h; sourceTree = "<group>"; };
84001FB41D0016380026C63F /* LFLiveVideoConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveVideoConfiguration.m; sourceTree = "<group>"; };
84001FB61D0016380026C63F /* LFGPUImageBeautyFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFGPUImageBeautyFilter.h; sourceTree = "<group>"; };
84001FB71D0016380026C63F /* LFGPUImageBeautyFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFGPUImageBeautyFilter.m; sourceTree = "<group>"; };
84001FB81D0016380026C63F /* LFGPUImageEmptyFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFGPUImageEmptyFilter.h; sourceTree = "<group>"; };
84001FB91D0016380026C63F /* LFGPUImageEmptyFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFGPUImageEmptyFilter.m; sourceTree = "<group>"; };
84001FBA1D0016380026C63F /* LFLiveSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveSession.h; sourceTree = "<group>"; };
84001FBB1D0016380026C63F /* LFLiveSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveSession.m; sourceTree = "<group>"; };
84001FBD1D0016380026C63F /* LFAudioFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioFrame.h; sourceTree = "<group>"; };
84001FBE1D0016380026C63F /* LFAudioFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFAudioFrame.m; sourceTree = "<group>"; };
84001FBF1D0016380026C63F /* LFFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFFrame.h; sourceTree = "<group>"; };
84001FC01D0016380026C63F /* LFFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFFrame.m; sourceTree = "<group>"; };
84001FC11D0016380026C63F /* LFLiveDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveDebug.h; sourceTree = "<group>"; };
84001FC21D0016380026C63F /* LFLiveDebug.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveDebug.m; sourceTree = "<group>"; };
84001FC31D0016380026C63F /* LFLiveStreamInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveStreamInfo.h; sourceTree = "<group>"; };
84001FC41D0016380026C63F /* LFLiveStreamInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveStreamInfo.m; sourceTree = "<group>"; };
84001FC51D0016380026C63F /* LFVideoFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoFrame.h; sourceTree = "<group>"; };
84001FC61D0016380026C63F /* LFVideoFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoFrame.m; sourceTree = "<group>"; };
84001FF61D0017590026C63F /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
84001FF81D00175D0026C63F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
84001FFA1D0017630026C63F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
84001FFC1D0017680026C63F /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
84001FFE1D00176C0026C63F /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; };
840020001D0017850026C63F /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
A17586B27CD6843997425CCF /* Pods-LFLiveKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LFLiveKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LFLiveKit/Pods-LFLiveKit.debug.xcconfig"; sourceTree = "<group>"; };
B289F1D41D3DE77F00D9C7A5 /* LFStreamingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LFStreamingBuffer.h; path = LFLiveKit/publish/LFStreamingBuffer.h; sourceTree = SOURCE_ROOT; };
B289F1D51D3DE77F00D9C7A5 /* LFStreamingBuffer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LFStreamingBuffer.m; path = LFLiveKit/publish/LFStreamingBuffer.m; sourceTree = SOURCE_ROOT; };
B289F1D61D3DE77F00D9C7A5 /* LFStreamRtmpSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LFStreamRtmpSocket.h; path = LFLiveKit/publish/LFStreamRtmpSocket.h; sourceTree = SOURCE_ROOT; };
B289F1D71D3DE77F00D9C7A5 /* LFStreamRtmpSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LFStreamRtmpSocket.m; path = LFLiveKit/publish/LFStreamRtmpSocket.m; sourceTree = SOURCE_ROOT; };
B289F1D81D3DE77F00D9C7A5 /* LFStreamSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LFStreamSocket.h; path = LFLiveKit/publish/LFStreamSocket.h; sourceTree = SOURCE_ROOT; };
B289F1D91D3DE77F00D9C7A5 /* NSMutableArray+LFAdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSMutableArray+LFAdd.h"; path = "LFLiveKit/publish/NSMutableArray+LFAdd.h"; sourceTree = SOURCE_ROOT; };
B289F1DA1D3DE77F00D9C7A5 /* NSMutableArray+LFAdd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSMutableArray+LFAdd.m"; path = "LFLiveKit/publish/NSMutableArray+LFAdd.m"; sourceTree = SOURCE_ROOT; };
B5758EB2A15DAA132D8BF380 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
B75B965E6B94DE4CBCC82EA7 /* Pods-LFLiveKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LFLiveKit.release.xcconfig"; path = "Pods/Target Support Files/Pods-LFLiveKit/Pods-LFLiveKit.release.xcconfig"; sourceTree = "<group>"; };
B8CB02D2A92EA1F5A262F154 /* libPods-LFLiveKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LFLiveKit.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
84001F861D0015D10026C63F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
840020011D0017850026C63F /* libz.tbd in Frameworks */,
84001FFF1D00176C0026C63F /* VideoToolbox.framework in Frameworks */,
84001FFD1D0017680026C63F /* AudioToolbox.framework in Frameworks */,
84001FFB1D0017630026C63F /* UIKit.framework in Frameworks */,
84001FF91D00175D0026C63F /* Foundation.framework in Frameworks */,
84001FF71D0017590026C63F /* AVFoundation.framework in Frameworks */,
AD7F89B4621A7EFEBEA72D49 /* libPods-LFLiveKit.a in Frameworks */,
BE55DA79155500CDEF87FB5C /* libPods.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
84001F911D0015D10026C63F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
84001F951D0015D10026C63F /* LFLiveKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0C07D14560B9E91EA1B59306 /* Frameworks */ = {
isa = PBXGroup;
children = (
840020001D0017850026C63F /* libz.tbd */,
84001FFE1D00176C0026C63F /* VideoToolbox.framework */,
84001FFC1D0017680026C63F /* AudioToolbox.framework */,
84001FFA1D0017630026C63F /* UIKit.framework */,
84001FF81D00175D0026C63F /* Foundation.framework */,
84001FF61D0017590026C63F /* AVFoundation.framework */,
B8CB02D2A92EA1F5A262F154 /* libPods-LFLiveKit.a */,
B5758EB2A15DAA132D8BF380 /* libPods.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
84001F801D0015D10026C63F = {
isa = PBXGroup;
children = (
84001F8C1D0015D10026C63F /* LFLiveKit */,
84001F981D0015D10026C63F /* LFLiveKitTests */,
84001F8B1D0015D10026C63F /* Products */,
EDD4B76A07A6817C79BB4E5C /* Pods */,
0C07D14560B9E91EA1B59306 /* Frameworks */,
);
sourceTree = "<group>";
};
84001F8B1D0015D10026C63F /* Products */ = {
isa = PBXGroup;
children = (
84001F8A1D0015D10026C63F /* LFLiveKit.framework */,
84001F941D0015D10026C63F /* LFLiveKitTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
84001F8C1D0015D10026C63F /* LFLiveKit */ = {
isa = PBXGroup;
children = (
84001F8D1D0015D10026C63F /* LFLiveKit.h */,
84001FBA1D0016380026C63F /* LFLiveSession.h */,
84001FBB1D0016380026C63F /* LFLiveSession.m */,
84001FBC1D0016380026C63F /* objects */,
84001FB01D0016380026C63F /* configuration */,
84001FA41D0016380026C63F /* capture */,
84001FA91D0016380026C63F /* coder */,
84001FB51D0016380026C63F /* filter */,
84001FC91D0016380026C63F /* publish */,
84001F8F1D0015D10026C63F /* Info.plist */,
);
path = LFLiveKit;
sourceTree = "<group>";
};
84001F981D0015D10026C63F /* LFLiveKitTests */ = {
isa = PBXGroup;
children = (
84001F991D0015D10026C63F /* LFLiveKitTests.m */,
84001F9B1D0015D10026C63F /* Info.plist */,
);
path = LFLiveKitTests;
sourceTree = "<group>";
};
84001FA41D0016380026C63F /* capture */ = {
isa = PBXGroup;
children = (
84001FA51D0016380026C63F /* LFAudioCapture.h */,
84001FA61D0016380026C63F /* LFAudioCapture.m */,
84001FA71D0016380026C63F /* LFVideoCapture.h */,
84001FA81D0016380026C63F /* LFVideoCapture.m */,
);
path = capture;
sourceTree = "<group>";
};
84001FA91D0016380026C63F /* coder */ = {
isa = PBXGroup;
children = (
84001FAA1D0016380026C63F /* LFAudioEncoding.h */,
84001FAB1D0016380026C63F /* LFHardwareAudioEncoder.h */,
84001FAC1D0016380026C63F /* LFHardwareAudioEncoder.m */,
84001FAD1D0016380026C63F /* LFHardwareVideoEncoder.h */,
84001FAE1D0016380026C63F /* LFHardwareVideoEncoder.m */,
84001FAF1D0016380026C63F /* LFVideoEncoding.h */,
);
path = coder;
sourceTree = "<group>";
};
84001FB01D0016380026C63F /* configuration */ = {
isa = PBXGroup;
children = (
84001FB11D0016380026C63F /* LFLiveAudioConfiguration.h */,
84001FB21D0016380026C63F /* LFLiveAudioConfiguration.m */,
84001FB31D0016380026C63F /* LFLiveVideoConfiguration.h */,
84001FB41D0016380026C63F /* LFLiveVideoConfiguration.m */,
);
path = configuration;
sourceTree = "<group>";
};
84001FB51D0016380026C63F /* filter */ = {
isa = PBXGroup;
children = (
84001FB61D0016380026C63F /* LFGPUImageBeautyFilter.h */,
84001FB71D0016380026C63F /* LFGPUImageBeautyFilter.m */,
84001FB81D0016380026C63F /* LFGPUImageEmptyFilter.h */,
84001FB91D0016380026C63F /* LFGPUImageEmptyFilter.m */,
);
path = filter;
sourceTree = "<group>";
};
84001FBC1D0016380026C63F /* objects */ = {
isa = PBXGroup;
children = (
84001FBD1D0016380026C63F /* LFAudioFrame.h */,
84001FBE1D0016380026C63F /* LFAudioFrame.m */,
84001FBF1D0016380026C63F /* LFFrame.h */,
84001FC01D0016380026C63F /* LFFrame.m */,
84001FC11D0016380026C63F /* LFLiveDebug.h */,
84001FC21D0016380026C63F /* LFLiveDebug.m */,
84001FC31D0016380026C63F /* LFLiveStreamInfo.h */,
84001FC41D0016380026C63F /* LFLiveStreamInfo.m */,
84001FC51D0016380026C63F /* LFVideoFrame.h */,
84001FC61D0016380026C63F /* LFVideoFrame.m */,
);
path = objects;
sourceTree = "<group>";
};
84001FC91D0016380026C63F /* publish */ = {
isa = PBXGroup;
children = (
B289F1D41D3DE77F00D9C7A5 /* LFStreamingBuffer.h */,
B289F1D51D3DE77F00D9C7A5 /* LFStreamingBuffer.m */,
B289F1D61D3DE77F00D9C7A5 /* LFStreamRtmpSocket.h */,
B289F1D71D3DE77F00D9C7A5 /* LFStreamRtmpSocket.m */,
B289F1D81D3DE77F00D9C7A5 /* LFStreamSocket.h */,
B289F1D91D3DE77F00D9C7A5 /* NSMutableArray+LFAdd.h */,
B289F1DA1D3DE77F00D9C7A5 /* NSMutableArray+LFAdd.m */,
);
name = publish;
path = upload;
sourceTree = "<group>";
};
EDD4B76A07A6817C79BB4E5C /* Pods */ = {
isa = PBXGroup;
children = (
A17586B27CD6843997425CCF /* Pods-LFLiveKit.debug.xcconfig */,
B75B965E6B94DE4CBCC82EA7 /* Pods-LFLiveKit.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
84001F871D0015D10026C63F /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
84001FDB1D0016380026C63F /* LFLiveAudioConfiguration.h in Headers */,
B289F1DD1D3DE77F00D9C7A5 /* LFStreamRtmpSocket.h in Headers */,
84001FDD1D0016380026C63F /* LFLiveVideoConfiguration.h in Headers */,
84001FE31D0016380026C63F /* LFLiveSession.h in Headers */,
B289F1DB1D3DE77F00D9C7A5 /* LFStreamingBuffer.h in Headers */,
84001FEB1D0016380026C63F /* LFLiveStreamInfo.h in Headers */,
84001FE91D0016380026C63F /* LFLiveDebug.h in Headers */,
84001FE71D0016380026C63F /* LFFrame.h in Headers */,
84001FD61D0016380026C63F /* LFHardwareAudioEncoder.h in Headers */,
B289F1E01D3DE77F00D9C7A5 /* NSMutableArray+LFAdd.h in Headers */,
84001FDF1D0016380026C63F /* LFGPUImageBeautyFilter.h in Headers */,
84001FD31D0016380026C63F /* LFVideoCapture.h in Headers */,
84001FD11D0016380026C63F /* LFAudioCapture.h in Headers */,
84001FE11D0016380026C63F /* LFGPUImageEmptyFilter.h in Headers */,
84001FDA1D0016380026C63F /* LFVideoEncoding.h in Headers */,
84001FE51D0016380026C63F /* LFAudioFrame.h in Headers */,
84001FED1D0016380026C63F /* LFVideoFrame.h in Headers */,
84001FD81D0016380026C63F /* LFHardwareVideoEncoder.h in Headers */,
B289F1DF1D3DE77F00D9C7A5 /* LFStreamSocket.h in Headers */,
84001FD51D0016380026C63F /* LFAudioEncoding.h in Headers */,
84001F8E1D0015D10026C63F /* LFLiveKit.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
84001F891D0015D10026C63F /* LFLiveKit */ = {
isa = PBXNativeTarget;
buildConfigurationList = 84001F9E1D0015D10026C63F /* Build configuration list for PBXNativeTarget "LFLiveKit" */;
buildPhases = (
8EE9401DCA9508E918B7FB68 /* 📦 Check Pods Manifest.lock */,
98F2C3F394BD79A6D6B8424F /* Check Pods Manifest.lock */,
84001F851D0015D10026C63F /* Sources */,
84001F861D0015D10026C63F /* Frameworks */,
84001F871D0015D10026C63F /* Headers */,
84001F881D0015D10026C63F /* Resources */,
817C22141AD3F2EB34365AA3 /* 📦 Copy Pods Resources */,
8A5D8B623E50AAC1575D1741 /* Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = LFLiveKit;
productName = LFLiveKit;
productReference = 84001F8A1D0015D10026C63F /* LFLiveKit.framework */;
productType = "com.apple.product-type.framework";
};
84001F931D0015D10026C63F /* LFLiveKitTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 84001FA11D0015D10026C63F /* Build configuration list for PBXNativeTarget "LFLiveKitTests" */;
buildPhases = (
84001F901D0015D10026C63F /* Sources */,
84001F911D0015D10026C63F /* Frameworks */,
84001F921D0015D10026C63F /* Resources */,
);
buildRules = (
);
dependencies = (
84001F971D0015D10026C63F /* PBXTargetDependency */,
);
name = LFLiveKitTests;
productName = LFLiveKitTests;
productReference = 84001F941D0015D10026C63F /* LFLiveKitTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
84001F811D0015D10026C63F /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = admin;
TargetAttributes = {
84001F891D0015D10026C63F = {
CreatedOnToolsVersion = 7.3;
};
84001F931D0015D10026C63F = {
CreatedOnToolsVersion = 7.3;
};
};
};
buildConfigurationList = 84001F841D0015D10026C63F /* Build configuration list for PBXProject "LFLiveKit" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 84001F801D0015D10026C63F;
productRefGroup = 84001F8B1D0015D10026C63F /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
84001F891D0015D10026C63F /* LFLiveKit */,
84001F931D0015D10026C63F /* LFLiveKitTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
84001F881D0015D10026C63F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
84001F921D0015D10026C63F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
817C22141AD3F2EB34365AA3 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LFLiveKit/Pods-LFLiveKit-resources.sh\"\n";
showEnvVarsInLog = 0;
};
8A5D8B623E50AAC1575D1741 /* Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
showEnvVarsInLog = 0;
};
8EE9401DCA9508E918B7FB68 /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
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";
showEnvVarsInLog = 0;
};
98F2C3F394BD79A6D6B8424F /* Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
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";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
84001F851D0015D10026C63F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
84001FE21D0016380026C63F /* LFGPUImageEmptyFilter.m in Sources */,
84001FE41D0016380026C63F /* LFLiveSession.m in Sources */,
84001FE61D0016380026C63F /* LFAudioFrame.m in Sources */,
84001FDC1D0016380026C63F /* LFLiveAudioConfiguration.m in Sources */,
84001FD41D0016380026C63F /* LFVideoCapture.m in Sources */,
84001FE81D0016380026C63F /* LFFrame.m in Sources */,
B289F1DC1D3DE77F00D9C7A5 /* LFStreamingBuffer.m in Sources */,
B289F1E11D3DE77F00D9C7A5 /* NSMutableArray+LFAdd.m in Sources */,
84001FDE1D0016380026C63F /* LFLiveVideoConfiguration.m in Sources */,
84001FD21D0016380026C63F /* LFAudioCapture.m in Sources */,
B289F1DE1D3DE77F00D9C7A5 /* LFStreamRtmpSocket.m in Sources */,
84001FD91D0016380026C63F /* LFHardwareVideoEncoder.m in Sources */,
84001FEC1D0016380026C63F /* LFLiveStreamInfo.m in Sources */,
84001FEA1D0016380026C63F /* LFLiveDebug.m in Sources */,
84001FEE1D0016380026C63F /* LFVideoFrame.m in Sources */,
84001FD71D0016380026C63F /* LFHardwareAudioEncoder.m in Sources */,
84001FE01D0016380026C63F /* LFGPUImageBeautyFilter.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
84001F901D0015D10026C63F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
84001F9A1D0015D10026C63F /* LFLiveKitTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
84001F971D0015D10026C63F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 84001F891D0015D10026C63F /* LFLiveKit */;
targetProxy = 84001F961D0015D10026C63F /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
84001F9C1D0015D10026C63F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
84001F9D1D0015D10026C63F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
84001F9F1D0015D10026C63F /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = A17586B27CD6843997425CCF /* Pods-LFLiveKit.debug.xcconfig */;
buildSettings = {
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = LFLiveKit/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKit.LFLiveKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
84001FA01D0015D10026C63F /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B75B965E6B94DE4CBCC82EA7 /* Pods-LFLiveKit.release.xcconfig */;
buildSettings = {
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = LFLiveKit/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKit.LFLiveKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
84001FA21D0015D10026C63F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
INFOPLIST_FILE = LFLiveKitTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKit.LFLiveKitTests;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
84001FA31D0015D10026C63F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
INFOPLIST_FILE = LFLiveKitTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKit.LFLiveKitTests;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
84001F841D0015D10026C63F /* Build configuration list for PBXProject "LFLiveKit" */ = {
isa = XCConfigurationList;
buildConfigurations = (
84001F9C1D0015D10026C63F /* Debug */,
84001F9D1D0015D10026C63F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
84001F9E1D0015D10026C63F /* Build configuration list for PBXNativeTarget "LFLiveKit" */ = {
isa = XCConfigurationList;
buildConfigurations = (
84001F9F1D0015D10026C63F /* Debug */,
84001FA01D0015D10026C63F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
84001FA11D0015D10026C63F /* Build configuration list for PBXNativeTarget "LFLiveKitTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
84001FA21D0015D10026C63F /* Debug */,
84001FA31D0015D10026C63F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 84001F811D0015D10026C63F /* Project object */;
}
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:LFLiveKit.xcodeproj">
</FileRef>
</Workspace>
@@ -1,155 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "48F687CDE9990BD471D7883061F7E5D4"
BuildableName = "libCocoaAsyncSocket.a"
BlueprintName = "CocoaAsyncSocket"
ReferencedContainer = "container:Pods/Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6610362E50A6DE8BACCA1F2885CD9157"
BuildableName = "libGPUImage.a"
BlueprintName = "GPUImage"
ReferencedContainer = "container:Pods/Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7C2BDDF89D4243C7BCA44592D146DEED"
BuildableName = "libPods-LFLiveKit.a"
BlueprintName = "Pods-LFLiveKit"
ReferencedContainer = "container:Pods/Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84001F891D0015D10026C63F"
BuildableName = "LFLiveKit.framework"
BlueprintName = "LFLiveKit"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84001F931D0015D10026C63F"
BuildableName = "LFLiveKitTests.xctest"
BlueprintName = "LFLiveKitTests"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84001F931D0015D10026C63F"
BuildableName = "LFLiveKitTests.xctest"
BlueprintName = "LFLiveKitTests"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84001F891D0015D10026C63F"
BuildableName = "LFLiveKit.framework"
BlueprintName = "LFLiveKit"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84001F891D0015D10026C63F"
BuildableName = "LFLiveKit.framework"
BlueprintName = "LFLiveKit"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84001F891D0015D10026C63F"
BuildableName = "LFLiveKit.framework"
BlueprintName = "LFLiveKit"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -1,27 +0,0 @@
<?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>SchemeUserState</key>
<dict>
<key>LFLiveKit.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>84001F891D0015D10026C63F</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>84001F931D0015D10026C63F</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
@@ -1,19 +0,0 @@
<?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>SuppressBuildableAutocreation</key>
<dict>
<key>84001F891D0015D10026C63F</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>84001F931D0015D10026C63F</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:LFLiveKit.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
+9 -2
View File
@@ -2,10 +2,13 @@
// LFLiveKit.h
// LFLiveKit
//
// Created by admin on 16/5/24.
// Copyright © 2016年 admin. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#ifndef LFLiveKit_h
#define LFLiveKit_h
#import "LFLiveSession.h"
#import "LFLiveAudioConfiguration.h"
#import "LFLiveVideoConfiguration.h"
@@ -13,3 +16,7 @@
#import "LFFrame.h"
#import "LFLiveStreamInfo.h"
#import "LFVideoFrame.h"
#import "LFLiveDebug.h"
#endif
+59 -5
View File
@@ -2,8 +2,9 @@
// LFLiveSession.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
//
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -16,6 +17,28 @@
#import "LFLiveDebug.h"
typedef NS_ENUM(NSInteger,LFLiveCaptureType) {
LFLiveCaptureAudio, //< capture only audio
LFLiveCaptureVideo, //< capture onlt video
LFLiveInputAudio, //< only audio (External input audio)
LFLiveInputVideo, //< only video (External input video)
};
///< 用来控制采集类型(可以内部采集也可以外部传入等各种组合,支持单音频与单视频,外部输入适用于录屏,无人机等外设介入)
typedef NS_ENUM(NSInteger,LFLiveCaptureTypeMask) {
LFLiveCaptureMaskAudio = (1 << LFLiveCaptureAudio), ///< only inner capture audio (no video)
LFLiveCaptureMaskVideo = (1 << LFLiveCaptureVideo), ///< only inner capture video (no audio)
LFLiveInputMaskAudio = (1 << LFLiveInputAudio), ///< only outer input audio (no video)
LFLiveInputMaskVideo = (1 << LFLiveInputVideo), ///< only outer input video (no audio)
LFLiveCaptureMaskAll = (LFLiveCaptureMaskAudio | LFLiveCaptureMaskVideo), ///< inner capture audio and video
LFLiveInputMaskAll = (LFLiveInputMaskAudio | LFLiveInputMaskVideo), ///< outer input audio and video(method see pushVideo and pushAudio)
LFLiveCaptureMaskAudioInputVideo = (LFLiveCaptureMaskAudio | LFLiveInputMaskVideo), ///< inner capture audio and outer input video(method pushVideo and setRunning)
LFLiveCaptureMaskVideoInputAudio = (LFLiveCaptureMaskVideo | LFLiveInputMaskAudio), ///< inner capture video and outer input audio(method pushAudio and setRunning)
LFLiveCaptureDefaultMask = LFLiveCaptureMaskAll ///< default is inner capture audio and video
};
@class LFLiveSession;
@protocol LFLiveSessionDelegate <NSObject>
@@ -51,10 +74,10 @@
/** The beautyFace control capture shader filter empty or beautiy */
@property (nonatomic, assign) BOOL beautyFace;
/** The beautyLevel control beautyFace Level, default 0.5, between 0.0 ~ 1.0 */
/** The beautyLevel control beautyFace Level. Default is 0.5, between 0.0 ~ 1.0 */
@property (nonatomic, assign) CGFloat beautyLevel;
/** The brightLevel control brightness Level, default 0.5, between 0.0 ~ 1.0 */
/** The brightLevel control brightness Level, Default is 0.5, between 0.0 ~ 1.0 */
@property (nonatomic, assign) CGFloat brightLevel;
/** The torch control camera zoom scale default 1.0, between 1.0 ~ 3.0 */
@@ -69,12 +92,18 @@
/** The muted control callbackAudioData,muted will memset 0.*/
@property (nonatomic, assign) BOOL muted;
/* The adaptiveBitrate control auto adjust bitrate. Default is NO */
@property (nonatomic, assign) BOOL adaptiveBitrate;
/** The stream control upload and package*/
@property (nullable, nonatomic, strong, readonly) LFLiveStreamInfo *streamInfo;
/** The status of the stream .*/
@property (nonatomic, assign, readonly) LFLiveState state;
/** The captureType control inner or outer audio and video .*/
@property (nonatomic, assign, readonly) LFLiveCaptureTypeMask captureType;
/** The showDebugInfo control streamInfo and uploadInfo(1s) *.*/
@property (nonatomic, assign) BOOL showDebugInfo;
@@ -84,6 +113,20 @@
/** The reconnectCount control reconnect count (重连次数) *.*/
@property (nonatomic, assign) NSUInteger reconnectCount;
/*** The warterMarkView control whether the watermark is displayed or not ,if set ni,will remove watermark,otherwise add.
set alpha represent mix.Position relative to outVideoSize.
*.*/
@property (nonatomic, strong, nullable) UIView *warterMarkView;
/* The currentImage is videoCapture shot */
@property (nonatomic, strong,readonly ,nullable) UIImage *currentImage;
/* The saveLocalVideo is save the local video */
@property (nonatomic, assign) BOOL saveLocalVideo;
/* The saveLocalVideoPath is save the local video path */
@property (nonatomic, strong, nullable) NSURL *saveLocalVideoPath;
#pragma mark - Initializer
///=============================================================================
/// @name Initializer
@@ -95,7 +138,13 @@
The designated initializer. Multiple instances with the same configuration will make the
capture unstable.
*/
- (nullable instancetype)initWithAudioConfiguration:(nullable LFLiveAudioConfiguration *)audioConfiguration videoConfiguration:(nullable LFLiveVideoConfiguration *)videoConfiguration NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithAudioConfiguration:(nullable LFLiveAudioConfiguration *)audioConfiguration videoConfiguration:(nullable LFLiveVideoConfiguration *)videoConfiguration;
/**
The designated initializer. Multiple instances with the same configuration will make the
capture unstable.
*/
- (nullable instancetype)initWithAudioConfiguration:(nullable LFLiveAudioConfiguration *)audioConfiguration videoConfiguration:(nullable LFLiveVideoConfiguration *)videoConfiguration captureType:(LFLiveCaptureTypeMask)captureType NS_DESIGNATED_INITIALIZER;
/** The start stream .*/
- (void)startLive:(nonnull LFLiveStreamInfo *)streamInfo;
@@ -103,6 +152,11 @@
/** The stop stream .*/
- (void)stopLive;
/** support outer input yuv or rgb video(set LFLiveCaptureTypeMask) .*/
- (void)pushVideo:(nullable CVPixelBufferRef)pixelBuffer;
/** support outer input pcm audio(set LFLiveCaptureTypeMask) .*/
- (void)pushAudio:(nullable NSData*)audioData;
@end
+158 -57
View File
@@ -2,8 +2,8 @@
// LFLiveSession.m
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFLiveSession.h"
@@ -11,19 +11,18 @@
#import "LFAudioCapture.h"
#import "LFHardwareVideoEncoder.h"
#import "LFHardwareAudioEncoder.h"
#import "LFH264VideoEncoder.h"
#import "LFStreamRTMPSocket.h"
#import "LFLiveStreamInfo.h"
#import "LFGPUImageBeautyFilter.h"
#import "LFH264VideoEncoder.h"
#define LFLiveReportKey @"com.youku.liveSessionReport"
@interface LFLiveSession ()<LFAudioCaptureDelegate, LFVideoCaptureDelegate, LFAudioEncodingDelegate, LFVideoEncodingDelegate, LFStreamSocketDelegate>
{
dispatch_semaphore_t _lock;
}
///音频配置
/// 音频配置
@property (nonatomic, strong) LFLiveAudioConfiguration *audioConfiguration;
///视频配置
/// 视频配置
@property (nonatomic, strong) LFLiveVideoConfiguration *videoConfiguration;
/// 声音采集
@property (nonatomic, strong) LFAudioCapture *audioCaptureSource;
@@ -36,46 +35,63 @@
/// 上传
@property (nonatomic, strong) id<LFStreamSocket> socket;
#pragma mark -- 内部标识
/// 上报
@property (nonatomic, copy) dispatch_block_t reportBlock;
/// debugInfo
/// 调试信息
@property (nonatomic, strong) LFLiveDebug *debugInfo;
/// streamInfo
/// 流信息
@property (nonatomic, strong) LFLiveStreamInfo *streamInfo;
/// uploading
/// 是否开始上传
@property (nonatomic, assign) BOOL uploading;
/// state
/// 当前状态
@property (nonatomic, assign, readwrite) LFLiveState state;
/// 当前直播type
@property (nonatomic, assign, readwrite) LFLiveCaptureTypeMask captureType;
/// 时间戳锁
@property (nonatomic, strong) dispatch_semaphore_t lock;
@end
/**  时间戳 */
#define NOW (CACurrentMediaTime()*1000)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
@interface LFLiveSession ()
@property (nonatomic, assign) uint64_t timestamp;
@property (nonatomic, assign) BOOL isFirstFrame;
@property (nonatomic, assign) uint64_t currentTimestamp;
/// 上传相对时间戳
@property (nonatomic, assign) uint64_t relativeTimestamps;
/// 音视频是否对齐
@property (nonatomic, assign) BOOL AVAlignment;
/// 当前是否采集到了音频
@property (nonatomic, assign) BOOL hasCaptureAudio;
/// 当前是否采集到了关键帧
@property (nonatomic, assign) BOOL hasKeyFrameVideo;
@end
@implementation LFLiveSession
#pragma mark -- LifeCycle
- (instancetype)initWithAudioConfiguration:(LFLiveAudioConfiguration *)audioConfiguration videoConfiguration:(LFLiveVideoConfiguration *)videoConfiguration {
if (!audioConfiguration || !videoConfiguration) @throw [NSException exceptionWithName:@"LFLiveSession init error" reason:@"audioConfiguration or videoConfiguration is nil " userInfo:nil];
- (instancetype)initWithAudioConfiguration:(nullable LFLiveAudioConfiguration *)audioConfiguration videoConfiguration:(nullable LFLiveVideoConfiguration *)videoConfiguration {
return [self initWithAudioConfiguration:audioConfiguration videoConfiguration:videoConfiguration captureType:LFLiveCaptureDefaultMask];
}
- (nullable instancetype)initWithAudioConfiguration:(nullable LFLiveAudioConfiguration *)audioConfiguration videoConfiguration:(nullable LFLiveVideoConfiguration *)videoConfiguration captureType:(LFLiveCaptureTypeMask)captureType{
if((captureType & LFLiveCaptureMaskAudio || captureType & LFLiveInputMaskAudio) && !audioConfiguration) @throw [NSException exceptionWithName:@"LFLiveSession init error" reason:@"audioConfiguration is nil " userInfo:nil];
if((captureType & LFLiveCaptureMaskVideo || captureType & LFLiveInputMaskVideo) && !videoConfiguration) @throw [NSException exceptionWithName:@"LFLiveSession init error" reason:@"videoConfiguration is nil " userInfo:nil];
if (self = [super init]) {
_audioConfiguration = audioConfiguration;
_videoConfiguration = videoConfiguration;
_lock = dispatch_semaphore_create(1);
_adaptiveBitrate = NO;
_captureType = captureType;
}
return self;
}
- (void)dealloc {
self.audioCaptureSource.running = NO;
self.videoCaptureSource.running = NO;
_videoCaptureSource.running = NO;
_audioCaptureSource.running = NO;
}
#pragma mark -- CustomMethod
@@ -90,35 +106,67 @@
- (void)stopLive {
self.uploading = NO;
[self.socket stop];
self.socket = nil;
}
- (void)pushVideo:(nullable CVPixelBufferRef)pixelBuffer{
if(self.captureType & LFLiveInputMaskVideo){
if (self.uploading) [self.videoEncoder encodeVideoData:pixelBuffer timeStamp:NOW];
}
}
- (void)pushAudio:(nullable NSData*)audioData{
if(self.captureType & LFLiveInputMaskAudio){
if (self.uploading) [self.audioEncoder encodeAudioData:audioData timeStamp:NOW];
}
}
#pragma mark -- PrivateMethod
- (void)pushSendBuffer:(LFFrame*)frame{
if(self.relativeTimestamps == 0){
self.relativeTimestamps = frame.timestamp;
}
frame.timestamp = [self uploadTimestamp:frame.timestamp];
[self.socket sendFrame:frame];
}
#pragma mark -- CaptureDelegate
- (void)captureOutput:(nullable LFAudioCapture *)capture audioBuffer:(AudioBufferList)inBufferList {
if (self.uploading) [self.audioEncoder encodeAudioData:inBufferList timeStamp:self.currentTimestamp];
- (void)captureOutput:(nullable LFAudioCapture *)capture audioData:(nullable NSData*)audioData {
if (self.uploading) [self.audioEncoder encodeAudioData:audioData timeStamp:NOW];
}
- (void)captureOutput:(nullable LFVideoCapture *)capture pixelBuffer:(nullable CVImageBufferRef)pixelBuffer {
if (self.uploading) [self.videoEncoder encodeVideoData:pixelBuffer timeStamp:self.currentTimestamp];
- (void)captureOutput:(nullable LFVideoCapture *)capture pixelBuffer:(nullable CVPixelBufferRef)pixelBuffer {
if (self.uploading) [self.videoEncoder encodeVideoData:pixelBuffer timeStamp:NOW];
}
#pragma mark -- EncoderDelegate
- (void)audioEncoder:(nullable id<LFAudioEncoding>)encoder audioFrame:(nullable LFAudioFrame *)frame {
if (self.uploading) [self.socket sendFrame:frame]; //<上传
//<上传 时间戳对齐
if (self.uploading){
self.hasCaptureAudio = YES;
if(self.AVAlignment) [self pushSendBuffer:frame];
}
}
- (void)videoEncoder:(nullable id<LFVideoEncoding>)encoder videoFrame:(nullable LFVideoFrame *)frame {
if (self.uploading) [self.socket sendFrame:frame]; //<上传
//<上传 时间戳对齐
if (self.uploading){
if(frame.isKeyFrame && self.hasCaptureAudio) self.hasKeyFrameVideo = YES;
if(self.AVAlignment) [self pushSendBuffer:frame];
}
}
#pragma mark -- LFStreamTcpSocketDelegate
- (void)socketStatus:(nullable id<LFStreamSocket>)socket status:(LFLiveState)status {
if (status == LFLiveStart) {
if (!self.uploading) {
self.timestamp = 0;
self.isFirstFrame = YES;
self.AVAlignment = NO;
self.hasCaptureAudio = NO;
self.hasKeyFrameVideo = NO;
self.relativeTimestamps = 0;
self.uploading = YES;
}
}else if(status == LFLiveStop || status == LFLiveError){
} else if(status == LFLiveStop || status == LFLiveError){
self.uploading = NO;
}
dispatch_async(dispatch_get_main_queue(), ^{
@@ -149,16 +197,20 @@
}
- (void)socketBufferStatus:(nullable id<LFStreamSocket>)socket status:(LFLiveBuffferState)status {
NSUInteger videoBitRate = [_videoEncoder videoBitRate];
if (status == LFLiveBuffferDecline) {
if (videoBitRate < _videoConfiguration.videoMaxBitRate) {
videoBitRate = videoBitRate + 50 * 1000;
[_videoEncoder setVideoBitRate:videoBitRate];
}
} else {
if (videoBitRate > _videoConfiguration.videoMinBitRate) {
videoBitRate = videoBitRate - 100 * 1000;
[_videoEncoder setVideoBitRate:videoBitRate];
if((self.captureType & LFLiveCaptureMaskVideo || self.captureType & LFLiveInputMaskVideo) && self.adaptiveBitrate){
NSUInteger videoBitRate = [self.videoEncoder videoBitRate];
if (status == LFLiveBuffferDecline) {
if (videoBitRate < _videoConfiguration.videoMaxBitRate) {
videoBitRate = videoBitRate + 50 * 1000;
[self.videoEncoder setVideoBitRate:videoBitRate];
NSLog(@"Increase bitrate %@", @(videoBitRate));
}
} else {
if (videoBitRate > self.videoConfiguration.videoMinBitRate) {
videoBitRate = videoBitRate - 100 * 1000;
[self.videoEncoder setVideoBitRate:videoBitRate];
NSLog(@"Decline bitrate %@", @(videoBitRate));
}
}
}
}
@@ -199,6 +251,23 @@
[self didChangeValueForKey:@"beautyFace"];
}
- (BOOL)saveLocalVideo{
return self.videoCaptureSource.saveLocalVideo;
}
- (void)setSaveLocalVideo:(BOOL)saveLocalVideo{
[self.videoCaptureSource setSaveLocalVideo:saveLocalVideo];
}
- (NSURL*)saveLocalVideoPath{
return self.videoCaptureSource.saveLocalVideoPath;
}
- (void)setSaveLocalVideoPath:(NSURL*)saveLocalVideoPath{
[self.videoCaptureSource setSaveLocalVideoPath:saveLocalVideoPath];
}
- (BOOL)beautyFace {
return self.videoCaptureSource.beautyFace;
}
@@ -263,18 +332,34 @@
return self.audioCaptureSource.muted;
}
- (void)setWarterMarkView:(UIView *)warterMarkView{
[self.videoCaptureSource setWarterMarkView:warterMarkView];
}
- (nullable UIView*)warterMarkView{
return self.videoCaptureSource.warterMarkView;
}
- (nullable UIImage *)currentImage{
return self.videoCaptureSource.currentImage;
}
- (LFAudioCapture *)audioCaptureSource {
if (!_audioCaptureSource) {
_audioCaptureSource = [[LFAudioCapture alloc] initWithAudioConfiguration:_audioConfiguration];
_audioCaptureSource.delegate = self;
if(self.captureType & LFLiveCaptureMaskAudio){
_audioCaptureSource = [[LFAudioCapture alloc] initWithAudioConfiguration:_audioConfiguration];
_audioCaptureSource.delegate = self;
}
}
return _audioCaptureSource;
}
- (LFVideoCapture *)videoCaptureSource {
if (!_videoCaptureSource) {
_videoCaptureSource = [[LFVideoCapture alloc] initWithVideoConfiguration:_videoConfiguration];
_videoCaptureSource.delegate = self;
if(self.captureType & LFLiveCaptureMaskVideo){
_videoCaptureSource = [[LFVideoCapture alloc] initWithVideoConfiguration:_videoConfiguration];
_videoCaptureSource.delegate = self;
}
}
return _videoCaptureSource;
}
@@ -289,7 +374,11 @@
- (id<LFVideoEncoding>)videoEncoder {
if (!_videoEncoder) {
_videoEncoder = [[LFHardwareVideoEncoder alloc] initWithVideoStreamConfiguration:_videoConfiguration];
if([[UIDevice currentDevice].systemVersion floatValue] < 8.0){
_videoEncoder = [[LFH264VideoEncoder alloc] initWithVideoStreamConfiguration:_videoConfiguration];
}else{
_videoEncoder = [[LFHardwareVideoEncoder alloc] initWithVideoStreamConfiguration:_videoConfiguration];
}
[_videoEncoder setDelegate:self];
}
return _videoEncoder;
@@ -297,7 +386,7 @@
- (id<LFStreamSocket>)socket {
if (!_socket) {
_socket = [[LFStreamRTMPSocket alloc] initWithStream:self.streamInfo videoSize:self.videoConfiguration.videoSize reconnectInterval:self.reconnectInterval reconnectCount:self.reconnectCount];
_socket = [[LFStreamRTMPSocket alloc] initWithStream:self.streamInfo reconnectInterval:self.reconnectInterval reconnectCount:self.reconnectCount];
[_socket setDelegate:self];
}
return _socket;
@@ -310,18 +399,30 @@
return _streamInfo;
}
- (uint64_t)currentTimestamp {
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
uint64_t currentts = 0;
if (_isFirstFrame == true) {
_timestamp = NOW;
_isFirstFrame = false;
currentts = 0;
} else {
currentts = NOW - _timestamp;
- (dispatch_semaphore_t)lock{
if(!_lock){
_lock = dispatch_semaphore_create(1);
}
dispatch_semaphore_signal(_lock);
return _lock;
}
- (uint64_t)uploadTimestamp:(uint64_t)captureTimestamp{
dispatch_semaphore_wait(self.lock, DISPATCH_TIME_FOREVER);
uint64_t currentts = 0;
currentts = captureTimestamp - self.relativeTimestamps;
dispatch_semaphore_signal(self.lock);
return currentts;
}
- (BOOL)AVAlignment{
if((self.captureType & LFLiveCaptureMaskAudio || self.captureType & LFLiveInputMaskAudio) &&
(self.captureType & LFLiveCaptureMaskVideo || self.captureType & LFLiveInputMaskVideo)
){
if(self.hasCaptureAudio && self.hasKeyFrameVideo) return YES;
else return NO;
}else{
return YES;
}
}
@end
+3 -3
View File
@@ -2,8 +2,8 @@
// LFAudioCapture.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/1.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -17,7 +17,7 @@ extern NSString *_Nullable const LFAudioComponentFailedToCreateNotification;
@class LFAudioCapture;
/** LFAudioCapture callback audioData */
@protocol LFAudioCaptureDelegate <NSObject>
- (void)captureOutput:(nullable LFAudioCapture *)capture audioBuffer:(AudioBufferList)inBufferList;
- (void)captureOutput:(nullable LFAudioCapture *)capture audioData:(nullable NSData*)audioData;
@end
+43 -54
View File
@@ -2,8 +2,8 @@
// LFAudioCapture.m
// LFLiveKit
//
// Created by 倾慕 on 16/5/1.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFAudioCapture.h"
@@ -18,61 +18,52 @@ NSString *const LFAudioComponentFailedToCreateNotification = @"LFAudioComponentF
@property (nonatomic, assign) AudioComponent component;
@property (nonatomic, strong) dispatch_queue_t taskQueue;
@property (nonatomic, assign) BOOL isRunning;
@property (nonatomic, strong) LFLiveAudioConfiguration *configuration;
@property (nonatomic, strong,nullable) LFLiveAudioConfiguration *configuration;
@end
@implementation LFAudioCapture
#pragma mark -- LiftCycle
- (instancetype)initWithAudioConfiguration:(LFLiveAudioConfiguration *)configuration {
if (self = [super init]) {
- (instancetype)initWithAudioConfiguration:(LFLiveAudioConfiguration *)configuration{
if(self = [super init]){
_configuration = configuration;
self.isRunning = NO;
self.taskQueue = dispatch_queue_create("com.youku.Laifeng.audioCapture.Queue", NULL);
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleRouteChange:)
name:AVAudioSessionRouteChangeNotification
object:session];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleInterruption:)
name:AVAudioSessionInterruptionNotification
object:session];
NSError *error = nil;
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[session setMode:AVAudioSessionModeVideoRecording error:&error];
if (![session setActive:YES error:&error]) {
[self handleAudioComponentCreationFailure];
}
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(handleRouteChange:)
name: AVAudioSessionRouteChangeNotification
object: session];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(handleInterruption:)
name: AVAudioSessionInterruptionNotification
object: session];
AudioComponentDescription acd;
acd.componentType = kAudioUnitType_Output;
//acd.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
acd.componentSubType = kAudioUnitSubType_RemoteIO;
acd.componentManufacturer = kAudioUnitManufacturer_Apple;
acd.componentFlags = 0;
acd.componentFlagsMask = 0;
self.component = AudioComponentFindNext(NULL, &acd);
OSStatus status = noErr;
status = AudioComponentInstanceNew(self.component, &_componetInstance);
if (noErr != status) {
[self handleAudioComponentCreationFailure];
}
UInt32 flagOne = 1;
AudioUnitSetProperty(self.componetInstance, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &flagOne, sizeof(flagOne));
AudioStreamBasicDescription desc = {0};
desc.mSampleRate = _configuration.audioSampleRate;
desc.mFormatID = kAudioFormatLinearPCM;
@@ -82,22 +73,23 @@ NSString *const LFAudioComponentFailedToCreateNotification = @"LFAudioComponentF
desc.mBitsPerChannel = 16;
desc.mBytesPerFrame = desc.mBitsPerChannel / 8 * desc.mChannelsPerFrame;
desc.mBytesPerPacket = desc.mBytesPerFrame * desc.mFramesPerPacket;
AURenderCallbackStruct cb;
cb.inputProcRefCon = (__bridge void *)(self);
cb.inputProc = handleInputBuffer;
AudioUnitSetProperty(self.componetInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &desc, sizeof(desc));
AudioUnitSetProperty(self.componetInstance, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 1, &cb, sizeof(cb));
status = AudioUnitInitialize(self.componetInstance);
if (noErr != status) {
[self handleAudioComponentCreationFailure];
}
[session setPreferredSampleRate:_configuration.audioSampleRate error:nil];
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers error:nil];
[session setActive:YES withOptions:kAudioSessionSetActiveFlag_NotifyOthersOnDeactivation error:nil];
[session setActive:YES error:nil];
}
return self;
@@ -106,8 +98,9 @@ NSString *const LFAudioComponentFailedToCreateNotification = @"LFAudioComponentF
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
dispatch_sync(self.taskQueue, ^{
dispatch_async(self.taskQueue, ^{
if (self.componetInstance) {
self.isRunning = NO;
AudioOutputUnitStop(self.componetInstance);
AudioComponentInstanceDispose(self.componetInstance);
self.componetInstance = nil;
@@ -124,10 +117,15 @@ NSString *const LFAudioComponentFailedToCreateNotification = @"LFAudioComponentF
dispatch_async(self.taskQueue, ^{
self.isRunning = YES;
NSLog(@"MicrophoneSource: startRunning");
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers error:nil];
AudioOutputUnitStart(self.componetInstance);
});
} else {
self.isRunning = NO;
dispatch_async(self.taskQueue, ^{
self.isRunning = NO;
NSLog(@"MicrophoneSource: stopRunning");
AudioOutputUnitStop(self.componetInstance);
});
}
}
@@ -184,7 +182,7 @@ NSString *const LFAudioComponentFailedToCreateNotification = @"LFAudioComponentF
reason = [[[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey] integerValue];
if (reason == AVAudioSessionInterruptionTypeBegan) {
if (self.isRunning) {
dispatch_sync(self.taskQueue, ^{
dispatch_async(self.taskQueue, ^{
NSLog(@"MicrophoneSource: stopRunning");
AudioOutputUnitStop(self.componetInstance);
});
@@ -198,7 +196,7 @@ NSString *const LFAudioComponentFailedToCreateNotification = @"LFAudioComponentF
case AVAudioSessionInterruptionOptionShouldResume:
if (self.isRunning) {
dispatch_async(self.taskQueue, ^{
NSLog(@"MicrophoneSource: stopRunning");
NSLog(@"MicrophoneSource: startRunning");
AudioOutputUnitStart(self.componetInstance);
});
}
@@ -241,15 +239,6 @@ static OSStatus handleInputBuffer(void *inRefCon,
inNumberFrames,
&buffers);
if (!source.isRunning) {
dispatch_sync(source.taskQueue, ^{
NSLog(@"MicrophoneSource: stopRunning");
AudioOutputUnitStop(source.componetInstance);
});
return status;
}
if (source.muted) {
for (int i = 0; i < buffers.mNumberBuffers; i++) {
AudioBuffer ab = buffers.mBuffers[i];
@@ -258,8 +247,8 @@ static OSStatus handleInputBuffer(void *inRefCon,
}
if (!status) {
if (source.delegate && [source.delegate respondsToSelector:@selector(captureOutput:audioBuffer:)]) {
[source.delegate captureOutput:source audioBuffer:buffers];
if (source.delegate && [source.delegate respondsToSelector:@selector(captureOutput:audioData:)]) {
[source.delegate captureOutput:source audioData:[NSData dataWithBytes:buffers.mBuffers[0].mData length:buffers.mBuffers[0].mDataByteSize]];
}
}
return status;
+15 -3
View File
@@ -2,8 +2,8 @@
// LFVideoCapture.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/1.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -13,7 +13,7 @@
@class LFVideoCapture;
/** LFVideoCapture callback videoData */
@protocol LFVideoCaptureDelegate <NSObject>
- (void)captureOutput:(nullable LFVideoCapture *)capture pixelBuffer:(nullable CVImageBufferRef)pixelBuffer;
- (void)captureOutput:(nullable LFVideoCapture *)capture pixelBuffer:(nullable CVPixelBufferRef)pixelBuffer;
@end
@interface LFVideoCapture : NSObject
@@ -56,6 +56,18 @@
/** The videoFrameRate control videoCapture output data count */
@property (nonatomic, assign) NSInteger videoFrameRate;
/*** The warterMarkView control whether the watermark is displayed or not ,if set ni,will remove watermark,otherwise add *.*/
@property (nonatomic, strong, nullable) UIView *warterMarkView;
/* The currentImage is videoCapture shot */
@property (nonatomic, strong, nullable) UIImage *currentImage;
/* The saveLocalVideo is save the local video */
@property (nonatomic, assign) BOOL saveLocalVideo;
/* The saveLocalVideoPath is save the local video path */
@property (nonatomic, strong, nullable) NSURL *saveLocalVideoPath;
#pragma mark - Initializer
///=============================================================================
/// @name Initializer
+214 -131
View File
@@ -2,24 +2,37 @@
// LFVideoCapture.m
// LFLiveKit
//
// Created by 倾慕 on 16/5/1.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFVideoCapture.h"
#import "GPUImage.h"
#import "LFGPUImageBeautyFilter.h"
#import "LFGPUImageEmptyFilter.h"
#if __has_include(<GPUImage/GPUImage.h>)
#import <GPUImage/GPUImage.h>
#elif __has_include("GPUImage/GPUImage.h")
#import "GPUImage/GPUImage.h"
#else
#import "GPUImage.h"
#endif
@interface LFVideoCapture ()
@property(nonatomic, strong) GPUImageVideoCamera *videoCamera;
@property(nonatomic, weak) LFGPUImageBeautyFilter *beautyFilter;
@property(nonatomic, strong) GPUImageOutput<GPUImageInput> *filter;
@property(nonatomic, strong) GPUImageOutput<GPUImageInput> *output;
@property(nonatomic, strong) GPUImageCropFilter *cropfilter;
@property(nonatomic, strong) GPUImageView *gpuImageView;
@property(nonatomic, strong) LFLiveVideoConfiguration *configuration;
@property (nonatomic, strong) GPUImageVideoCamera *videoCamera;
@property (nonatomic, strong) LFGPUImageBeautyFilter *beautyFilter;
@property (nonatomic, strong) GPUImageOutput<GPUImageInput> *filter;
@property (nonatomic, strong) GPUImageCropFilter *cropfilter;
@property (nonatomic, strong) GPUImageOutput<GPUImageInput> *output;
@property (nonatomic, strong) GPUImageView *gpuImageView;
@property (nonatomic, strong) LFLiveVideoConfiguration *configuration;
@property (nonatomic, strong) GPUImageAlphaBlendFilter *blendFilter;
@property (nonatomic, strong) GPUImageUIElement *uiElementInput;
@property (nonatomic, strong) UIView *waterMarkContentView;
@property (nonatomic, strong) GPUImageMovieWriter *movieWriter;
@end
@@ -33,44 +46,16 @@
- (instancetype)initWithVideoConfiguration:(LFLiveVideoConfiguration *)configuration {
if (self = [super init]) {
_configuration = configuration;
_videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:_configuration.avSessionPreset cameraPosition:AVCaptureDevicePositionFront];
UIInterfaceOrientation statusBar = [[UIApplication sharedApplication] statusBarOrientation];
if (configuration.landscape) {
if (statusBar != UIInterfaceOrientationLandscapeLeft && statusBar != UIInterfaceOrientationLandscapeRight) {
NSLog(@"当前设置方向出错");
NSLog(@"当前设置方向出错");
NSLog(@"当前设置方向出错");
_videoCamera.outputImageOrientation = UIInterfaceOrientationLandscapeLeft;
} else {
_videoCamera.outputImageOrientation = statusBar;
}
} else {
if (statusBar != UIInterfaceOrientationPortrait && statusBar != UIInterfaceOrientationPortraitUpsideDown) {
NSLog(@"当前设置方向出错");
NSLog(@"当前设置方向出错");
NSLog(@"当前设置方向出错");
_videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
} else {
_videoCamera.outputImageOrientation = statusBar;
}
}
_videoCamera.horizontallyMirrorFrontFacingCamera = NO;
_videoCamera.horizontallyMirrorRearFacingCamera = NO;
_videoCamera.frameRate = (int32_t)_configuration.videoFrameRate;
_gpuImageView = [[GPUImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[_gpuImageView setFillMode:kGPUImageFillModePreserveAspectRatioAndFill];
[_gpuImageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[_gpuImageView setInputRotation:kGPUImageFlipHorizonal atIndex:0];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterBackground:) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterForeground:) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarChanged:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
self.beautyFace = YES;
self.beautyLevel = 0.5;
self.brightLevel = 0.5;
self.zoomScale = 1.0;
self.mirror = YES;
}
return self;
}
@@ -79,67 +64,83 @@
[UIApplication sharedApplication].idleTimerDisabled = NO;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_videoCamera stopCameraCapture];
if(_gpuImageView){
[_gpuImageView removeFromSuperview];
_gpuImageView = nil;
}
}
#pragma mark -- Setter Getter
- (GPUImageVideoCamera *)videoCamera{
if(!_videoCamera){
_videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:_configuration.avSessionPreset cameraPosition:AVCaptureDevicePositionFront];
_videoCamera.outputImageOrientation = _configuration.outputImageOrientation;
_videoCamera.horizontallyMirrorFrontFacingCamera = NO;
_videoCamera.horizontallyMirrorRearFacingCamera = NO;
_videoCamera.frameRate = (int32_t)_configuration.videoFrameRate;
}
return _videoCamera;
}
- (void)setRunning:(BOOL)running {
if (_running == running) return;
_running = running;
if (!_running) {
[UIApplication sharedApplication].idleTimerDisabled = NO;
[_videoCamera stopCameraCapture];
[self.videoCamera stopCameraCapture];
if(self.saveLocalVideo) [self.movieWriter finishRecording];
} else {
[UIApplication sharedApplication].idleTimerDisabled = YES;
[_videoCamera startCameraCapture];
[self reloadFilter];
[self.videoCamera startCameraCapture];
if(self.saveLocalVideo) [self.movieWriter startRecording];
}
}
- (void)setPreView:(UIView *)preView {
if (_gpuImageView.superview) [_gpuImageView removeFromSuperview];
[preView insertSubview:_gpuImageView atIndex:0];
if (self.gpuImageView.superview) [self.gpuImageView removeFromSuperview];
[preView insertSubview:self.gpuImageView atIndex:0];
self.gpuImageView.frame = CGRectMake(0, 0, preView.frame.size.width, preView.frame.size.height);
}
- (UIView *)preView {
return _gpuImageView.superview;
return self.gpuImageView.superview;
}
- (void)setCaptureDevicePosition:(AVCaptureDevicePosition)captureDevicePosition {
[_videoCamera rotateCamera];
_videoCamera.frameRate = (int32_t)_configuration.videoFrameRate;
if (captureDevicePosition == AVCaptureDevicePositionFront) {
[_gpuImageView setInputRotation:kGPUImageFlipHorizonal atIndex:0];
} else {
[_gpuImageView setInputRotation:kGPUImageNoRotation atIndex:0];
}
[self.videoCamera rotateCamera];
self.videoCamera.frameRate = (int32_t)_configuration.videoFrameRate;
[self reloadMirror];
}
- (AVCaptureDevicePosition)captureDevicePosition {
return [_videoCamera cameraPosition];
return [self.videoCamera cameraPosition];
}
- (void)setVideoFrameRate:(NSInteger)videoFrameRate {
if (videoFrameRate <= 0) return;
if (videoFrameRate == _videoCamera.frameRate) return;
_videoCamera.frameRate = (uint32_t)videoFrameRate;
if (videoFrameRate == self.videoCamera.frameRate) return;
self.videoCamera.frameRate = (uint32_t)videoFrameRate;
}
- (NSInteger)videoFrameRate {
return _videoCamera.frameRate;
return self.videoCamera.frameRate;
}
- (void)setTorch:(BOOL)torch {
BOOL ret;
if (!_videoCamera.captureSession) return;
AVCaptureSession *session = (AVCaptureSession *)_videoCamera.captureSession;
if (!self.videoCamera.captureSession) return;
AVCaptureSession *session = (AVCaptureSession *)self.videoCamera.captureSession;
[session beginConfiguration];
if (_videoCamera.inputCamera) {
if (_videoCamera.inputCamera.torchAvailable) {
if (self.videoCamera.inputCamera) {
if (self.videoCamera.inputCamera.torchAvailable) {
NSError *err = nil;
if ([_videoCamera.inputCamera lockForConfiguration:&err]) {
[_videoCamera.inputCamera setTorchMode:(torch ? AVCaptureTorchModeOn : AVCaptureTorchModeOff) ];
[_videoCamera.inputCamera unlockForConfiguration];
ret = (_videoCamera.inputCamera.torchMode == AVCaptureTorchModeOn);
if ([self.videoCamera.inputCamera lockForConfiguration:&err]) {
[self.videoCamera.inputCamera setTorchMode:(torch ? AVCaptureTorchModeOn : AVCaptureTorchModeOff) ];
[self.videoCamera.inputCamera unlockForConfiguration];
ret = (self.videoCamera.inputCamera.torchMode == AVCaptureTorchModeOn);
} else {
NSLog(@"Error while locking device for torch: %@", err);
ret = false;
@@ -153,22 +154,22 @@
}
- (BOOL)torch {
return _videoCamera.inputCamera.torchMode;
return self.videoCamera.inputCamera.torchMode;
}
- (void)setMirror:(BOOL)mirror {
_videoCamera.horizontallyMirrorFrontFacingCamera = mirror;
_videoCamera.horizontallyMirrorRearFacingCamera = mirror;
_mirror = mirror;
}
- (BOOL)mirror {
return _videoCamera.horizontallyMirrorFrontFacingCamera;
- (void)setBeautyFace:(BOOL)beautyFace{
_beautyFace = beautyFace;
[self reloadFilter];
}
- (void)setBeautyLevel:(CGFloat)beautyLevel {
_beautyLevel = beautyLevel;
if (_beautyFilter) {
[_beautyFilter setBeautyLevel:_beautyLevel];
if (self.beautyFilter) {
[self.beautyFilter setBeautyLevel:_beautyLevel];
}
}
@@ -178,8 +179,8 @@
- (void)setBrightLevel:(CGFloat)brightLevel {
_brightLevel = brightLevel;
if (_beautyFilter) {
[_beautyFilter setBrightLevel:brightLevel];
if (self.beautyFilter) {
[self.beautyFilter setBrightLevel:brightLevel];
}
}
@@ -202,55 +203,67 @@
return _zoomScale;
}
- (void)setBeautyFace:(BOOL)beautyFace {
if (_beautyFace == beautyFace) return;
_beautyFace = beautyFace;
[_filter removeAllTargets];
[_cropfilter removeAllTargets];
[_videoCamera removeAllTargets];
if (_beautyFace) {
_output = [[LFGPUImageEmptyFilter alloc] init];
_filter = [[LFGPUImageBeautyFilter alloc] init];
_beautyFilter = _filter;
__weak typeof(self) _self = self;
[_output setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime time) {
[_self processVideo:output];
}];
} else {
_filter = [[LFGPUImageEmptyFilter alloc] init];
_beautyFilter = nil;
__weak typeof(self) _self = self;
[_filter setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime time) {
[_self processVideo:output];
}];
- (void)setWarterMarkView:(UIView *)warterMarkView{
if(_warterMarkView && _warterMarkView.superview){
[_warterMarkView removeFromSuperview];
_warterMarkView = nil;
}
_warterMarkView = warterMarkView;
self.blendFilter.mix = warterMarkView.alpha;
[self.waterMarkContentView addSubview:_warterMarkView];
[self reloadFilter];
}
if (_configuration.isClipVideo) {
if (_configuration.landscape) {
_cropfilter = [[GPUImageCropFilter alloc] initWithCropRegion:CGRectMake(0.125, 0, 0.75, 1)];
} else {
_cropfilter = [[GPUImageCropFilter alloc] initWithCropRegion:CGRectMake(0, 0.125, 1, 0.75)];
}
[_videoCamera addTarget:_cropfilter];
[_cropfilter addTarget:_filter];
} else {
[_videoCamera addTarget:_filter];
- (GPUImageUIElement *)uiElementInput{
if(!_uiElementInput){
_uiElementInput = [[GPUImageUIElement alloc] initWithView:self.waterMarkContentView];
}
return _uiElementInput;
}
if (_beautyFace) {
[_filter addTarget:_output];
[_output addTarget:_gpuImageView];
} else {
[_filter addTarget:_gpuImageView];
- (GPUImageAlphaBlendFilter *)blendFilter{
if(!_blendFilter){
_blendFilter = [[GPUImageAlphaBlendFilter alloc] init];
_blendFilter.mix = 1.0;
[_blendFilter disableSecondFrameCheck];
}
return _blendFilter;
}
if (_videoCamera.cameraPosition == AVCaptureDevicePositionFront) {
[_gpuImageView setInputRotation:kGPUImageFlipHorizonal atIndex:0];
} else {
[_gpuImageView setInputRotation:kGPUImageNoRotation atIndex:0];
- (UIView *)waterMarkContentView{
if(!_waterMarkContentView){
_waterMarkContentView = [UIView new];
_waterMarkContentView.frame = CGRectMake(0, 0, self.configuration.videoSize.width, self.configuration.videoSize.height);
_waterMarkContentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
return _waterMarkContentView;
}
- (GPUImageView *)gpuImageView{
if(!_gpuImageView){
_gpuImageView = [[GPUImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[_gpuImageView setFillMode:kGPUImageFillModePreserveAspectRatioAndFill];
[_gpuImageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
}
return _gpuImageView;
}
-(UIImage *)currentImage{
if(_filter){
[_filter useNextFrameForImageCapture];
return _filter.imageFromCurrentFramebuffer;
}
return nil;
}
- (GPUImageMovieWriter*)movieWriter{
if(!_movieWriter){
_movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:self.saveLocalVideoPath size:self.configuration.videoSize];
_movieWriter.encodingLiveVideo = YES;
_movieWriter.shouldPassthroughAudio = YES;
self.videoCamera.audioEncodingTarget = self.movieWriter;
}
return _movieWriter;
}
#pragma mark -- Custom Method
@@ -258,12 +271,79 @@
__weak typeof(self) _self = self;
@autoreleasepool {
GPUImageFramebuffer *imageFramebuffer = output.framebufferForOutput;
CVPixelBufferRef pixelBuffer = [imageFramebuffer pixelBuffer];
CVPixelBufferRef pixelBuffer = NULL;
CVPixelBufferCreateWithBytes(kCFAllocatorDefault, _self.configuration.videoSize.width, _self.configuration.videoSize.height, kCVPixelFormatType_32BGRA, [imageFramebuffer byteBuffer], _self.configuration.videoSize.width * 4, NULL, NULL, NULL, &pixelBuffer);
if (pixelBuffer && _self.delegate && [_self.delegate respondsToSelector:@selector(captureOutput:pixelBuffer:)]) {
[_self.delegate captureOutput:_self pixelBuffer:pixelBuffer];
}
CFRelease(pixelBuffer);
}
}
- (void)reloadFilter{
[self.filter removeAllTargets];
[self.blendFilter removeAllTargets];
[self.uiElementInput removeAllTargets];
[self.videoCamera removeAllTargets];
[self.output removeAllTargets];
[self.cropfilter removeAllTargets];
if (self.beautyFace) {
self.output = [[LFGPUImageEmptyFilter alloc] init];
self.filter = [[LFGPUImageBeautyFilter alloc] init];
self.beautyFilter = (LFGPUImageBeautyFilter*)self.filter;
} else {
self.output = [[LFGPUImageEmptyFilter alloc] init];
self.filter = [[LFGPUImageEmptyFilter alloc] init];
self.beautyFilter = nil;
}
///< 调节镜像
[self reloadMirror];
///< 480*640 比例为4:3 强制转换为16:9
if([self.configuration.avSessionPreset isEqualToString:AVCaptureSessionPreset640x480]){
CGRect cropRect = self.configuration.landscape ? CGRectMake(0, 0.125, 1, 0.75) : CGRectMake(0.125, 0, 0.75, 1);
self.cropfilter = [[GPUImageCropFilter alloc] initWithCropRegion:cropRect];
[self.videoCamera addTarget:self.cropfilter];
[self.cropfilter addTarget:self.filter];
}else{
[self.videoCamera addTarget:self.filter];
}
///< 添加水印
if(self.warterMarkView){
[self.filter addTarget:self.blendFilter];
[self.uiElementInput addTarget:self.blendFilter];
[self.blendFilter addTarget:self.gpuImageView];
if(self.saveLocalVideo) [self.blendFilter addTarget:self.movieWriter];
[self.filter addTarget:self.output];
[self.uiElementInput update];
}else{
[self.filter addTarget:self.output];
[self.output addTarget:self.gpuImageView];
if(self.saveLocalVideo) [self.output addTarget:self.movieWriter];
}
[self.filter forceProcessingAtSize:self.configuration.videoSize];
[self.output forceProcessingAtSize:self.configuration.videoSize];
[self.blendFilter forceProcessingAtSize:self.configuration.videoSize];
[self.uiElementInput forceProcessingAtSize:self.configuration.videoSize];
///< 输出数据
__weak typeof(self) _self = self;
[self.output setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime time) {
[_self processVideo:output];
}];
}
- (void)reloadMirror{
if(self.mirror && self.captureDevicePosition == AVCaptureDevicePositionFront){
self.videoCamera.horizontallyMirrorFrontFacingCamera = YES;
}else{
self.videoCamera.horizontallyMirrorFrontFacingCamera = NO;
}
}
@@ -271,31 +351,34 @@
- (void)willEnterBackground:(NSNotification *)notification {
[UIApplication sharedApplication].idleTimerDisabled = NO;
[_videoCamera pauseCameraCapture];
[self.videoCamera pauseCameraCapture];
runSynchronouslyOnVideoProcessingQueue(^{
glFinish();
});
}
- (void)willEnterForeground:(NSNotification *)notification {
[_videoCamera resumeCameraCapture];
[self.videoCamera resumeCameraCapture];
[UIApplication sharedApplication].idleTimerDisabled = YES;
}
- (void)statusBarChanged:(NSNotification *)notification {
NSLog(@"UIApplicationWillChangeStatusBarOrientationNotification. UserInfo: %@", notification.userInfo);
UIInterfaceOrientation statusBar = [[UIApplication sharedApplication] statusBarOrientation];
if (_configuration.landscape) {
if (statusBar == UIInterfaceOrientationLandscapeLeft) {
self.videoCamera.outputImageOrientation = UIInterfaceOrientationLandscapeRight;
} else if (statusBar == UIInterfaceOrientationLandscapeRight) {
self.videoCamera.outputImageOrientation = UIInterfaceOrientationLandscapeLeft;
}
} else {
if (statusBar == UIInterfaceOrientationPortrait) {
self.videoCamera.outputImageOrientation = UIInterfaceOrientationPortraitUpsideDown;
} else if (statusBar == UIInterfaceOrientationPortraitUpsideDown) {
self.videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
if(self.configuration.autorotate){
if (self.configuration.landscape) {
if (statusBar == UIInterfaceOrientationLandscapeLeft) {
self.videoCamera.outputImageOrientation = UIInterfaceOrientationLandscapeRight;
} else if (statusBar == UIInterfaceOrientationLandscapeRight) {
self.videoCamera.outputImageOrientation = UIInterfaceOrientationLandscapeLeft;
}
} else {
if (statusBar == UIInterfaceOrientationPortrait) {
self.videoCamera.outputImageOrientation = UIInterfaceOrientationPortraitUpsideDown;
} else if (statusBar == UIInterfaceOrientationPortraitUpsideDown) {
self.videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
}
}
}
}
+38
View File
@@ -0,0 +1,38 @@
//
// AVEncoder.h
// Encoder Demo
//
// Created by Geraint Davies on 14/01/2013.
// Copyright (c) 2013 GDCL http://www.gdcl.co.uk/license.htm
//
#import <Foundation/Foundation.h>
#import <AVFoundation/AVAssetWriter.h>
#import <AVFoundation/AVAssetWriterInput.h>
#import <AVFoundation/AVMediaFormat.h>
#import <AVFoundation/AVVideoSettings.h>
#import <sys/stat.h>
#import "LFVideoEncoder.h"
#import "LFMP4Atom.h"
typedef int (^encoder_handler_t)(NSArray *data, CMTimeValue ptsValue);
typedef int (^param_handler_t)(NSData *params);
@interface LFAVEncoder : NSObject
@property (atomic) NSUInteger bitrate;
+ (LFAVEncoder *)encoderForHeight:(int)height andWidth:(int)width bitrate:(int)bitrate;
- (void)encodeWithBlock:(encoder_handler_t)block onParams:(param_handler_t)paramsHandler;
- (void)encodeFrame:(CMSampleBufferRef)sampleBuffer;
- (NSData *)getConfigData;
- (void)shutdown;
@property (readonly, atomic) int bitspersecond;
@end
+439
View File
@@ -0,0 +1,439 @@
//
// AVEncoder.m
// Encoder Demo
//
// Created by Geraint Davies on 14/01/2013.
// Copyright (c) 2013 GDCL http://www.gdcl.co.uk/license.htm
//
#import "LFAVEncoder.h"
#import "LFNALUnit.h"
static void *AVEncoderContext = &AVEncoderContext;
static unsigned int to_host(unsigned char *p){
return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
}
#define OUTPUT_FILE_SWITCH_POINT (50 * 1024 * 1024) // 50 MB switch point
#define MAX_FILENAME_INDEX 5 // filenames "capture1.mp4" wraps at capture5.mp4
@interface LFAVEncoder ()
{
// initial writer, used to obtain SPS/PPS from header
LFVideoEncoder *_headerWriter;
// main encoder/writer
LFVideoEncoder *_writer;
// writer output file (input to our extractor) and monitoring
NSFileHandle *_inputFile;
dispatch_queue_t _readQueue;
dispatch_source_t _readSource;
// index of current file name
BOOL _swapping;
int _currentFile;
int _height;
int _width;
// param set data
NSData *_avcC;
int _lengthSize;
// location of mdat
BOOL _foundMDAT;
uint64_t _posMDAT;
int _bytesToNextAtom;
BOOL _needParams;
// tracking if NALU is next frame
int _prev_nal_idc;
int _prev_nal_type;
// array of NSData comprising a single frame. each data is one nalu with no start code
NSMutableArray *_pendingNALU;
// FIFO for frame times
NSMutableArray *_times;
encoder_handler_t _outputBlock;
param_handler_t _paramsBlock;
// estimate bitrate over first second
int _bitspersecond;
CMTimeValue _firstpts;
}
@property (atomic) BOOL bitrateChanged;
@end
@implementation LFAVEncoder
@synthesize bitspersecond = _bitspersecond;
+ (LFAVEncoder *)encoderForHeight:(int)height andWidth:(int)width bitrate:(int)bitrate {
LFAVEncoder *enc = [LFAVEncoder alloc];
[enc initForHeight:height andWidth:width bitrate:bitrate];
return enc;
}
- (NSString *)makeFilename {
NSString *filename = [NSString stringWithFormat:@"capture%d.mp4", _currentFile];
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
return path;
}
- (void)initForHeight:(int)height andWidth:(int)width bitrate:(int)bitrate {
_height = height;
_width = width;
_bitrate = bitrate;
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"params.mp4"];
_headerWriter = [LFVideoEncoder encoderForPath:path Height:height andWidth:width bitrate:(int)self.bitrate];
_times = [NSMutableArray arrayWithCapacity:10];
// swap between 3 filenames
_currentFile = 1;
_writer = [LFVideoEncoder encoderForPath:[self makeFilename] Height:height andWidth:width bitrate:(int)self.bitrate];
[self addObserver:self forKeyPath:NSStringFromSelector(@selector(bitrate)) options:0 context:AVEncoderContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (context == AVEncoderContext && [keyPath isEqualToString:NSStringFromSelector(@selector(bitrate))]) {
self.bitrateChanged = YES;
}
}
- (void)encodeWithBlock:(encoder_handler_t)block onParams:(param_handler_t)paramsHandler {
_outputBlock = block;
_paramsBlock = paramsHandler;
_needParams = YES;
_pendingNALU = nil;
_firstpts = -1;
_bitspersecond = 0;
}
- (BOOL)parseParams:(NSString *)path {
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
struct stat s;
fstat([file fileDescriptor], &s);
LFMP4Atom *movie = [LFMP4Atom atomAt:0 size:(int)s.st_size type:(OSType)('file') inFile:file];
LFMP4Atom *moov = [movie childOfType:(OSType)('moov') startAt:0];
LFMP4Atom *trak = nil;
if (moov != nil) {
for (;; ) {
trak = [moov nextChild];
if (trak == nil) {
break;
}
if (trak.type == (OSType)('trak')) {
LFMP4Atom *tkhd = [trak childOfType:(OSType)('tkhd') startAt:0];
NSData *verflags = [tkhd readAt:0 size:4];
unsigned char *p = (unsigned char *)[verflags bytes];
if (p[3] & 1) {
break;
} else {
tkhd = nil;
}
}
}
}
LFMP4Atom *stsd = nil;
if (trak != nil) {
LFMP4Atom *media = [trak childOfType:(OSType)('mdia') startAt:0];
if (media != nil) {
LFMP4Atom *minf = [media childOfType:(OSType)('minf') startAt:0];
if (minf != nil) {
LFMP4Atom *stbl = [minf childOfType:(OSType)('stbl') startAt:0];
if (stbl != nil) {
stsd = [stbl childOfType:(OSType)('stsd') startAt:0];
}
}
}
}
if (stsd != nil) {
LFMP4Atom *avc1 = [stsd childOfType:(OSType)('avc1') startAt:8];
if (avc1 != nil) {
LFMP4Atom *esd = [avc1 childOfType:(OSType)('avcC') startAt:78];
if (esd != nil) {
// this is the avcC record that we are looking for
_avcC = [esd readAt:0 size:(int)esd.length];
if (_avcC != nil) {
// extract size of length field
unsigned char *p = (unsigned char *)[_avcC bytes];
_lengthSize = (p[4] & 3) + 1;
return YES;
}
}
}
}
return NO;
}
- (void)onParamsCompletion {
// the initial one-frame-only file has been completed
// Extract the avcC structure and then start monitoring the
// main file to extract video from the mdat chunk.
if ([self parseParams:_headerWriter.path]) {
if (_paramsBlock) {
_paramsBlock(_avcC);
}
_headerWriter = nil;
_swapping = NO;
_inputFile = [NSFileHandle fileHandleForReadingAtPath:_writer.path];
_readQueue = dispatch_queue_create("uk.co.gdcl.avencoder.read", DISPATCH_QUEUE_SERIAL);
_readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, [_inputFile fileDescriptor], 0, _readQueue);
dispatch_source_set_event_handler(_readSource, ^{
[self onFileUpdate];
});
dispatch_resume(_readSource);
}
}
- (void)encodeFrame:(CMSampleBufferRef)sampleBuffer {
CMTime prestime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
NSNumber *pts = [NSNumber numberWithLongLong:prestime.value];
@synchronized(self){
if (_needParams) {
// the avcC record is needed for decoding and it's not written to the file until
// completion. We get round that by writing the first frame to two files; the first
// file (containing only one frame) is then finished, so we can extract the avcC record.
// Only when we've got that do we start reading from the main file.
_needParams = NO;
if ([_headerWriter encodeFrame:sampleBuffer]) {
[_headerWriter finishWithCompletionHandler:^{
[self onParamsCompletion];
}];
}
}
}
@synchronized(_times){
[_times addObject:pts];
}
@synchronized(self){
// switch output files when we reach a size limit
// to avoid runaway storage use.
if (!_swapping) {
struct stat st;
fstat([_inputFile fileDescriptor], &st);
if (st.st_size > OUTPUT_FILE_SWITCH_POINT || self.bitrateChanged) {
self.bitrateChanged = NO;
_swapping = YES;
LFVideoEncoder *oldVideo = _writer;
// construct a new writer to the next filename
if (++_currentFile > MAX_FILENAME_INDEX) {
_currentFile = 1;
}
//NSLog(@"Swap to file %d", _currentFile);
_writer = [LFVideoEncoder encoderForPath:[self makeFilename] Height:_height andWidth:_width bitrate:(int)self.bitrate];
// to do this seamlessly requires a few steps in the right order
// first, suspend the read source
if (_readSource) {
dispatch_source_cancel(_readSource);
// execute the next step as a block on the same queue, to be sure the suspend is done
dispatch_async(_readQueue, ^{
// finish the file, writing moov, before reading any more from the file
// since we don't yet know where the mdat ends
_readSource = nil;
[oldVideo finishWithCompletionHandler:^{
[self swapFiles:oldVideo.path];
}];
});
} else {
[self swapFiles:oldVideo.path];
}
}
}
[_writer encodeFrame:sampleBuffer];
}
}
- (void)swapFiles:(NSString *)oldPath {
// save current position
uint64_t pos = [_inputFile offsetInFile];
// re-read mdat length
[_inputFile seekToFileOffset:_posMDAT];
NSData *hdr = [_inputFile readDataOfLength:4];
unsigned char *p = (unsigned char *)[hdr bytes];
if (p) {
int lenMDAT = to_host(p);
// extract nalus from saved position to mdat end
uint64_t posEnd = _posMDAT + lenMDAT;
uint32_t cRead = (uint32_t)(posEnd - pos);
[_inputFile seekToFileOffset:pos];
[self readAndDeliver:cRead];
}
// close and remove file
[_inputFile closeFile];
_foundMDAT = false;
_bytesToNextAtom = 0;
[[NSFileManager defaultManager] removeItemAtPath:oldPath error:nil];
// open new file and set up dispatch source
_inputFile = [NSFileHandle fileHandleForReadingAtPath:_writer.path];
_readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, [_inputFile fileDescriptor], 0, _readQueue);
dispatch_source_set_event_handler(_readSource, ^{
[self onFileUpdate];
});
dispatch_resume(_readSource);
_swapping = NO;
}
- (void)readAndDeliver:(uint32_t)cReady {
// Identify the individual NALUs and extract them
while (cReady > _lengthSize) {
NSData *lenField = [_inputFile readDataOfLength:_lengthSize];
cReady -= _lengthSize;
unsigned char *p = (unsigned char *)[lenField bytes];
unsigned int lenNALU = to_host(p);
if (lenNALU > cReady) {
// whole NALU not present -- seek back to start of NALU and wait for more
[_inputFile seekToFileOffset:[_inputFile offsetInFile] - 4];
break;
}
NSData *nalu = [_inputFile readDataOfLength:lenNALU];
cReady -= lenNALU;
[self onNALU:nalu];
}
}
- (void)onFileUpdate {
// called whenever there is more data to read in the main encoder output file.
struct stat s;
fstat([_inputFile fileDescriptor], &s);
int cReady = (int)(s.st_size - [_inputFile offsetInFile]);
// locate the mdat atom if needed
while (!_foundMDAT && (cReady > 8)) {
if (_bytesToNextAtom == 0) {
NSData *hdr = [_inputFile readDataOfLength:8];
cReady -= 8;
unsigned char *p = (unsigned char *)[hdr bytes];
int lenAtom = to_host(p);
unsigned int nameAtom = to_host(p+4);
if (nameAtom == (unsigned int)('mdat')) {
_foundMDAT = true;
_posMDAT = [_inputFile offsetInFile] - 8;
} else {
_bytesToNextAtom = lenAtom - 8;
}
}
if (_bytesToNextAtom > 0) {
int cThis = cReady < _bytesToNextAtom ? cReady : _bytesToNextAtom;
_bytesToNextAtom -= cThis;
[_inputFile seekToFileOffset:[_inputFile offsetInFile]+cThis];
cReady -= cThis;
}
}
if (!_foundMDAT) {
return;
}
// the mdat must be just encoded video.
[self readAndDeliver:cReady];
}
- (void)onEncodedFrame {
CMTimeValue pts = 0;
@synchronized(_times){
if ([_times count] > 0) {
NSNumber *time = _times[0];
pts = [time longLongValue];
[_times removeObjectAtIndex:0];
if (_firstpts < 0) {
_firstpts = pts;
}
if ((pts - _firstpts) < 1) {
int bytes = 0;
for (NSData *data in _pendingNALU) {
bytes += [data length];
}
_bitspersecond += (bytes * 8);
}
} else {
//NSLog(@"no pts for buffer");
}
}
if (_outputBlock != nil) {
_outputBlock(_pendingNALU, pts);
}
}
// combine multiple NALUs into a single frame, and in the process, convert to BSF
// by adding 00 00 01 startcodes before each NALU.
- (void)onNALU:(NSData *)nalu {
unsigned char *pNal = (unsigned char *)[nalu bytes];
int idc = pNal[0] & 0x60;
int naltype = pNal[0] & 0x1f;
if (_pendingNALU) {
LFNALUnit nal(pNal, (int)[nalu length]);
// we have existing data —is this the same frame?
// typically there are a couple of NALUs per frame in iOS encoding.
// This is not general-purpose: it assumes that arbitrary slice ordering is not allowed.
BOOL bNew = NO;
if ((idc != _prev_nal_idc) && ((idc * _prev_nal_idc) == 0)) {
bNew = YES;
} else if ((naltype != _prev_nal_type) && ((naltype == 5) || (_prev_nal_type == 5))) {
bNew = YES;
} else if ((naltype >= 1) && (naltype <= 5)) {
nal.Skip(8);
int first_mb = (int)nal.GetUE();
if (first_mb == 0) {
bNew = YES;
}
}
if (bNew) {
[self onEncodedFrame];
_pendingNALU = nil;
}
}
_prev_nal_type = naltype;
_prev_nal_idc = idc;
if (_pendingNALU == nil) {
_pendingNALU = [NSMutableArray arrayWithCapacity:2];
}
[_pendingNALU addObject:nalu];
}
- (NSData *)getConfigData {
return [_avcC copy];
}
- (void)shutdown {
@synchronized(self){
_readSource = nil;
if (_headerWriter) {
[_headerWriter finishWithCompletionHandler:^{
_headerWriter = nil;
}];
}
if (_writer) {
[_writer finishWithCompletionHandler:^{
_writer = nil;
}];
}
// !! wait for these to finish before returning and delete temp files
}
}
@end
+30
View File
@@ -0,0 +1,30 @@
//
// LFMP4Atom.h
// Encoder Demo
//
// Created by Geraint Davies on 15/01/2013.
// Copyright (c) 2013 GDCL http://www.gdcl.co.uk/license.htm
//
#import <Foundation/Foundation.h>
@interface LFMP4Atom : NSObject
{
NSFileHandle *_file;
int64_t _offset;
int64_t _length;
OSType _type;
int64_t _nextChild;
}
@property OSType type;
@property int64_t length;
+ (LFMP4Atom *)atomAt:(int64_t)offset size:(int)length type:(OSType)fourcc inFile:(NSFileHandle *)handle;
- (BOOL)init:(int64_t)offset size:(int)length type:(OSType)fourcc inFile:(NSFileHandle *)handle;
- (NSData *)readAt:(int64_t)offset size:(int)length;
- (BOOL)setChildOffset:(int64_t)offset;
- (LFMP4Atom *)nextChild;
- (LFMP4Atom *)childOfType:(OSType)fourcc startAt:(int64_t)offset;
@end
+90
View File
@@ -0,0 +1,90 @@
//
// LFMP4Atom.m
// Encoder Demo
//
// Created by Geraint Davies on 15/01/2013.
// Copyright (c) 2013 GDCL http://www.gdcl.co.uk/license.htm
//
#import "LFMP4Atom.h"
static unsigned int to_host(unsigned char *p){
return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
}
@implementation LFMP4Atom
@synthesize type = _type;
@synthesize length = _length;
+ (LFMP4Atom *)atomAt:(int64_t)offset size:(int)length type:(OSType)fourcc inFile:(NSFileHandle *)handle {
LFMP4Atom *atom = [LFMP4Atom alloc];
if (![atom init:offset size:length type:fourcc inFile:handle]) {
return nil;
}
return atom;
}
- (BOOL)init:(int64_t)offset size:(int)length type:(OSType)fourcc inFile:(NSFileHandle *)handle {
_file = handle;
_offset = offset;
_length = length;
_type = fourcc;
_nextChild = 0;
return YES;
}
- (NSData *)readAt:(int64_t)offset size:(int)length {
[_file seekToFileOffset:_offset + offset];
return [_file readDataOfLength:length];
}
- (BOOL)setChildOffset:(int64_t)offset {
_nextChild = offset;
return YES;
}
- (LFMP4Atom *)nextChild {
if (_nextChild <= (_length - 8)) {
[_file seekToFileOffset:_offset + _nextChild];
NSData *data = [_file readDataOfLength:8];
int cHeader = 8;
unsigned char *p = (unsigned char *)[data bytes];
int64_t len = to_host(p);
OSType fourcc = to_host(p + 4);
if (len == 1) {
// 64-bit extended length
cHeader += 8;
data = [_file readDataOfLength:8];
p = (unsigned char *)[data bytes];
len = to_host(p);
len = (len << 32) + to_host(p + 4);
} else if (len == 0) {
// whole remaining parent space
len = _length - _nextChild;
}
if (fourcc == (OSType)('uuid')) {
cHeader += 16;
}
if ((len < 0) || ((len + _nextChild) > _length)) {
return nil;
}
int64_t offset = _nextChild + cHeader;
_nextChild += len;
len -= cHeader;
return [LFMP4Atom atomAt:offset+_offset size:(int)len type:fourcc inFile:_file];
}
return nil;
}
- (LFMP4Atom *)childOfType:(OSType)fourcc startAt:(int64_t)offset {
[self setChildOffset:offset];
LFMP4Atom *child = nil;
do {
child = [self nextChild];
} while ((child != nil) && (child.type != fourcc));
return child;
}
@end
+424
View File
@@ -0,0 +1,424 @@
//
// NALUnit.cpp
//
// Implementation of Basic parsing of H.264 NAL Units
//
// Geraint Davies, March 2004
//
// Copyright (c) GDCL 2004-2008 http://www.gdcl.co.uk/license.htm
#include "LFNALUnit.h"
// --- core NAL Unit implementation ------------------------------
LFNALUnit::LFNALUnit()
: m_pStart(NULL),
m_cBytes(0){
}
bool
LFNALUnit::GetStartCode(const BYTE *& pBegin, const BYTE *& pStart, int& cRemain){
// start code is any number of 00 followed by 00 00 01
// We need to record the first 00 in pBegin and the first byte
// following the startcode in pStart.
// if no start code is found, pStart and cRemain should be unchanged.
const BYTE *pThis = pStart;
int cBytes = cRemain;
pBegin = NULL;
while (cBytes >= 4) {
if (pThis[0] == 0) {
// remember first 00
if (pBegin == NULL) {
pBegin = pThis;
}
if ((pThis[1] == 0) &&
(pThis[2] == 1)) {
// point to type byte of NAL unit
pStart = pThis + 3;
cRemain = cBytes - 3;
return true;
}
} else {
pBegin = NULL;
}
cBytes--;
pThis++;
}
return false;
}
bool
LFNALUnit::Parse(const BYTE *pBuffer, int cSpace, int LengthSize, bool bEnd){
// if we get the start code but not the whole
// NALU, we can return false but still have the length property valid
m_cBytes = 0;
ResetBitstream();
if (LengthSize > 0) {
m_pStartCodeStart = pBuffer;
if (LengthSize > cSpace) {
return false;
}
m_cBytes = 0;
for (int i = 0; i < LengthSize; i++) {
m_cBytes <<= 8;
m_cBytes += *pBuffer++;
}
if ((m_cBytes+LengthSize) <= cSpace) {
m_pStart = pBuffer;
return true;
}
} else {
// this is not length-delimited: we must look for start codes
const BYTE *pBegin;
if (GetStartCode(pBegin, pBuffer, cSpace)) {
m_pStart = pBuffer;
m_pStartCodeStart = pBegin;
// either we find another startcode, or we continue to the
// buffer end (if this is the last block of data)
if (GetStartCode(pBegin, pBuffer, cSpace)) {
m_cBytes = int(pBegin - m_pStart);
return true;
} else if (bEnd) {
// current element extends to end of buffer
m_cBytes = cSpace;
return true;
}
}
}
return false;
}
// bitwise access to data
void
LFNALUnit::ResetBitstream(){
m_idx = 0;
m_nBits = 0;
m_cZeros = 0;
}
void
LFNALUnit::Skip(int nBits){
if (nBits < m_nBits) {
m_nBits -= nBits;
} else {
nBits -= m_nBits;
while (nBits >= 8) {
GetBYTE();
nBits -= 8;
}
if (nBits) {
m_byte = GetBYTE();
m_nBits = 8;
m_nBits -= nBits;
}
}
}
// get the next byte, removing emulation prevention bytes
BYTE
LFNALUnit::GetBYTE(){
if (m_idx >= m_cBytes) {
return 0;
}
BYTE b = m_pStart[m_idx++];
// to avoid start-code emulation, a byte 0x03 is inserted
// after any 00 00 pair. Discard that here.
if (b == 0) {
m_cZeros++;
if ((m_idx < m_cBytes) && (m_cZeros == 2) && (m_pStart[m_idx] == 0x03)) {
m_idx++;
m_cZeros = 0;
}
} else {
m_cZeros = 0;
}
return b;
}
unsigned long
LFNALUnit::GetBit(){
if (m_nBits == 0) {
m_byte = GetBYTE();
m_nBits = 8;
}
m_nBits--;
return (m_byte >> m_nBits) & 0x1;
}
unsigned long
LFNALUnit::GetWord(int nBits){
unsigned long u = 0;
while (nBits > 0) {
u <<= 1;
u |= GetBit();
nBits--;
}
return u;
}
unsigned long
LFNALUnit::GetUE(){
// Exp-Golomb entropy coding: leading zeros, then a one, then
// the data bits. The number of leading zeros is the number of
// data bits, counting up from that number of 1s as the base.
// That is, if you see
// 0001010
// You have three leading zeros, so there are three data bits (010)
// counting up from a base of 111: thus 111 + 010 = 1001 = 9
int cZeros = 0;
while (GetBit() == 0) {
cZeros++;
}
return GetWord(cZeros) + ((1 << cZeros)-1);
}
long
LFNALUnit::GetSE(){
// same as UE but signed.
// basically the unsigned numbers are used as codes to indicate signed numbers in pairs
// in increasing value. Thus the encoded values
// 0, 1, 2, 3, 4
// mean
// 0, 1, -1, 2, -2 etc
unsigned long UE = GetUE();
bool bPositive = UE & 1;
long SE = (UE + 1) >> 1;
if (!bPositive) {
SE = -SE;
}
return SE;
}
// --- sequence params parsing ---------------
LFSeqParamSet::LFSeqParamSet()
: m_cx(0),
m_cy(0),
m_FrameBits(0){
// SetRect(&m_rcFrame, 0, 0, 0, 0);
}
void
ScalingList(int size, LFNALUnit *pnalu){
long lastScale = 8;
long nextScale = 8;
for (int j = 0; j < size; j++) {
if (nextScale != 0) {
long delta = pnalu->GetSE();
nextScale = (lastScale + delta + 256) %256;
}
int scaling_list_j = (nextScale == 0) ? (int)lastScale : (int)nextScale;
lastScale = scaling_list_j;
}
}
bool
LFSeqParamSet::Parse(LFNALUnit *pnalu){
if (pnalu->Type() != LFNALUnit::NAL_Sequence_Params) {
return false;
}
// with the UE/SE type encoding, we must decode all the values
// to get through to the ones we want
pnalu->ResetBitstream();
pnalu->Skip(8); // type
m_Profile =(int) pnalu->GetWord(8);
m_Compatibility = (BYTE)pnalu->GetWord(8);
m_Level = (int)pnalu->GetWord(8);
/*int seq_param_id =*/ pnalu->GetUE();
if ((m_Profile == 100) || (m_Profile == 110) || (m_Profile == 122) || (m_Profile == 144)) {
int chroma_fmt = (int)pnalu->GetUE();
if (chroma_fmt == 3) {
pnalu->Skip(1);
}
/* int bit_depth_luma_minus8 = */ pnalu->GetUE();
/* int bit_depth_chroma_minus8 = */ pnalu->GetUE();
pnalu->Skip(1);
int seq_scaling_matrix_present = (int)pnalu->GetBit();
if (seq_scaling_matrix_present) {
for (int i = 0; i < 8; i++) {
if (pnalu->GetBit()) {
if (i < 6) {
ScalingList(16, pnalu);
} else {
ScalingList(64, pnalu);
}
}
}
}
}
int log2_frame_minus4 = (int)pnalu->GetUE();
m_FrameBits = log2_frame_minus4 + 4;
int POCtype = (int)pnalu->GetUE();
if (POCtype == 0) {
/*int log2_poc_minus4 =*/ pnalu->GetUE();
} else if (POCtype == 1) {
pnalu->Skip(1); // delta always zero
/*int nsp_offset =*/ pnalu->GetSE();
/*int nsp_top_to_bottom = */ pnalu->GetSE();
int num_ref_in_cycle = (int)pnalu->GetUE();
for (int i = 0; i < num_ref_in_cycle; i++) {
/*int sf_offset =*/ pnalu->GetSE();
}
} else if (POCtype != 2) {
return false;
}
// else for POCtype == 2, no additional data in stream
/*int num_ref_frames =*/ pnalu->GetUE();
/*int gaps_allowed =*/ pnalu->GetBit();
int mbs_width = (int)pnalu->GetUE();
int mbs_height = (int)pnalu->GetUE();
m_cx = (mbs_width+1) * 16;
m_cy = (mbs_height+1) * 16;
// smoke test validation of sps
if ((m_cx > 2000) || (m_cy > 2000)) {
return false;
}
// if this is false, then sizes are field sizes and need adjusting
m_bFrameOnly = pnalu->GetBit() ? true : false;
if (!m_bFrameOnly) {
pnalu->Skip(1); // adaptive frame/field
}
pnalu->Skip(1); // direct 8x8
#if 0
SetRect(&m_rcFrame, 0, 0, 0, 0);
bool bCrop = pnalu->GetBit() ? true : false;
if (bCrop) {
// get cropping rect
// store as exclusive, pixel parameters relative to frame
m_rcFrame.left = pnalu->GetUE() * 2;
m_rcFrame.right = pnalu->GetUE() * 2;
m_rcFrame.top = pnalu->GetUE() * 2;
m_rcFrame.bottom = pnalu->GetUE() * 2;
}
if (!IsRectEmpty(&m_rcFrame)) {
m_rcFrame.right = m_cx - m_rcFrame.right;
m_rcFrame.bottom = m_cy - m_rcFrame.bottom;
}
#endif
// adjust rect from 2x2 units to pixels
if (!m_bFrameOnly) {
// adjust heights from field to frame
m_cy *= 2;
#if 0
m_rcFrame.top *= 2;
m_rcFrame.bottom *= 2;
#endif
}
// .. rest are not interesting yet
m_nalu = *pnalu;
return true;
}
// --- slice header --------------------
bool
LFSliceHeader::Parse(LFNALUnit *pnalu){
switch (pnalu->Type()) {
case LFNALUnit::NAL_IDR_Slice:
case LFNALUnit::NAL_Slice:
case LFNALUnit::NAL_PartitionA:
// all these begin with a slice header
break;
default:
return false;
}
// slice header has the 1-byte type, then one UE value,
// then the frame number.
pnalu->ResetBitstream();
pnalu->Skip(8); // NALU type
pnalu->GetUE(); // first mb in slice
pnalu->GetUE(); // slice type
pnalu->GetUE(); // pic param set id
m_framenum = (int)pnalu->GetWord(m_nBitsFrame);
return true;
}
// --- SEI ----------------------
LFSEIMessage::LFSEIMessage(LFNALUnit *pnalu){
m_pnalu = pnalu;
const BYTE *p = pnalu->Start();
p++; // nalu type byte
m_type = 0;
while (*p == 0xff) {
m_type += 255;
p++;
}
m_type += *p;
p++;
m_length = 0;
while (*p == 0xff) {
m_type += 255;
p++;
}
m_length += *p;
p++;
m_idxPayload = int(p - m_pnalu->Start());
}
LFavcCHeader::LFavcCHeader(const BYTE *header, int cBytes){
if (cBytes < 8) {
return;
}
const BYTE *pEnd = header + cBytes;
int cSeq = header[5] & 0x1f;
header += 6;
for (int i = 0; i < cSeq; i++) {
if ((header+2) > pEnd) {
return;
}
int cThis = (header[0] << 8) + header[1];
header += 2;
if ((header+cThis) > pEnd) {
return;
}
if (i == 0) {
LFNALUnit n(header, cThis);
m_sps = n;
}
header += cThis;
}
if ((header + 3) >= pEnd) {
return;
}
int cPPS = header[0];
if (cPPS > 0) {
int cThis = (header[1] << 8) + header[2];
header += 3;
LFNALUnit n(header, cThis);
m_pps = n;
}
}
+242
View File
@@ -0,0 +1,242 @@
//
// NALUnit.h
//
// Basic parsing of H.264 NAL Units
//
// Geraint Davies, March 2004
//
// Copyright (c) GDCL 2004-2008 http://www.gdcl.co.uk/license.htm
#pragma once
typedef unsigned char BYTE;
typedef unsigned long ULONG;
#ifndef NULL
#define NULL 0
#endif
class LFNALUnit
{
public:
LFNALUnit();
LFNALUnit(const BYTE* pStart, int len){
m_pStart = m_pStartCodeStart = pStart;
m_cBytes = len;
ResetBitstream();
}
virtual ~LFNALUnit() {
}
// assignment copies a pointer into a fixed buffer managed elsewhere. We do not copy the data
LFNALUnit(const LFNALUnit &r){
m_pStart = r.m_pStart;
m_cBytes = r.m_cBytes;
ResetBitstream();
}
const LFNALUnit& operator = (const LFNALUnit &r)
{
m_pStart = r.m_pStart;
m_cBytes = r.m_cBytes;
ResetBitstream();
return *this;
}
enum eNALType {
NAL_Slice = 1,
NAL_PartitionA = 2,
NAL_PartitionB = 3,
NAL_PartitionC = 4,
NAL_IDR_Slice = 5,
NAL_SEI = 6,
NAL_Sequence_Params = 7,
NAL_Picture_Params = 8,
NAL_AUD = 9,
};
// identify a NAL unit within a buffer.
// If LengthSize is non-zero, it is the number of bytes
// of length field we expect. Otherwise, we expect start-code
// delimiters.
bool Parse(const BYTE *pBuffer, int cSpace, int LengthSize, bool bEnd);
eNALType Type(){
if (m_pStart == NULL) {
return eNALType(0);
}
return eNALType(m_pStart[0] & 0x1F);
}
int Length(){
return m_cBytes;
}
const BYTE *Start(){
return m_pStart;
}
// bitwise access to data
void ResetBitstream();
void Skip(int nBits);
unsigned long GetWord(int nBits);
unsigned long GetUE();
long GetSE();
BYTE GetBYTE();
unsigned long GetBit();
const BYTE *StartCodeStart() {
return m_pStartCodeStart;
}
private:
bool GetStartCode(const BYTE *& pBegin, const BYTE *& pStart, int& cRemain);
private:
const BYTE *m_pStartCodeStart;
const BYTE *m_pStart;
int m_cBytes;
// bitstream access
int m_idx;
int m_nBits;
BYTE m_byte;
int m_cZeros;
};
// simple parser for the Sequence parameter set things that we need
class LFSeqParamSet
{
public:
LFSeqParamSet();
bool Parse(LFNALUnit *pnalu);
int FrameBits(){
return m_FrameBits;
}
long EncodedWidth(){
return m_cx;
}
long EncodedHeight(){
return m_cy;
}
#if 0
long CroppedWidth(){
if (IsRectEmpty(&m_rcFrame)) {
return EncodedWidth();
}
return m_rcFrame.right - m_rcFrame.left;
}
long CroppedHeight(){
if (IsRectEmpty(&m_rcFrame)) {
return EncodedHeight();
}
return m_rcFrame.bottom - m_rcFrame.top;
}
RECT *CropRect(){
return &m_rcFrame;
}
#endif
bool Interlaced(){
return !m_bFrameOnly;
}
unsigned int Profile() {
return m_Profile;
}
unsigned int Level() {
return m_Level;
}
BYTE Compat() {
return m_Compatibility;
}
LFNALUnit *NALU() {
return &m_nalu;
}
private:
LFNALUnit m_nalu;
int m_FrameBits;
long m_cx;
long m_cy;
// RECT m_rcFrame;
bool m_bFrameOnly;
int m_Profile;
int m_Level;
BYTE m_Compatibility;
};
// extract frame num from slice headers
class LFSliceHeader
{
public:
LFSliceHeader(int nBitsFrame)
: m_framenum(0),
m_nBitsFrame(nBitsFrame){
}
bool Parse(LFNALUnit *pnalu);
int FrameNum(){
return m_framenum;
}
private:
int m_framenum;
int m_nBitsFrame;
};
// SEI message structure
class LFSEIMessage
{
public:
LFSEIMessage(LFNALUnit* pnalu);
int Type() {
return m_type;
}
int Length() {
return m_length;
}
const BYTE *Payload() {
return m_pnalu->Start() + m_idxPayload;
}
private:
LFNALUnit *m_pnalu;
int m_type;
int m_length;
int m_idxPayload;
};
// avcC structure from MP4
class LFavcCHeader
{
public:
LFavcCHeader(const BYTE* header, int cBytes);
LFNALUnit *sps() {
return &m_sps;
}
LFNALUnit *pps() {
return &m_pps;
}
private:
LFNALUnit m_sps;
LFNALUnit m_pps;
};
+27
View File
@@ -0,0 +1,27 @@
//
// VideoEncoder.h
// Encoder Demo
//
// Created by Geraint Davies on 14/01/2013.
// Copyright (c) 2013 GDCL http://www.gdcl.co.uk/license.htm
//
#import <Foundation/Foundation.h>
#import <AVFoundation/AVAssetWriter.h>
#import <AVFoundation/AVAssetWriterInput.h>
#import <AVFoundation/AVMediaFormat.h>
#import <AVFoundation/AVVideoSettings.h>
@interface LFVideoEncoder : NSObject
@property NSString *path;
@property (nonatomic, readonly) NSUInteger bitrate;
+ (LFVideoEncoder *)encoderForPath:(NSString *)path Height:(int)height andWidth:(int)width bitrate:(int)bitrate;
- (void)initPath:(NSString *)path Height:(int)height andWidth:(int)width bitrate:(int)bitrate;
- (void)finishWithCompletionHandler:(void (^)(void))handler;
- (BOOL)encodeFrame:(CMSampleBufferRef)sampleBuffer;
@end
+76
View File
@@ -0,0 +1,76 @@
//
// LFVideoEncoder.m
// Encoder Demo
//
// Created by Geraint Davies on 14/01/2013.
// Copyright (c) 2013 GDCL http://www.gdcl.co.uk/license.htm
//
#import "LFVideoEncoder.h"
@implementation LFVideoEncoder
{
AVAssetWriter *_writer;
AVAssetWriterInput *_writerInput;
NSString *_path;
}
@synthesize path = _path;
+ (LFVideoEncoder *)encoderForPath:(NSString *)path Height:(int)height andWidth:(int)width bitrate:(int)bitrate {
LFVideoEncoder *enc = [LFVideoEncoder alloc];
[enc initPath:path Height:height andWidth:width bitrate:bitrate];
return enc;
}
- (void)initPath:(NSString *)path Height:(int)height andWidth:(int)width bitrate:(int)bitrate {
self.path = path;
_bitrate = bitrate;
[[NSFileManager defaultManager] removeItemAtPath:self.path error:nil];
NSURL *url = [NSURL fileURLWithPath:self.path];
NSDictionary *settings = @{
AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey: @(width),
AVVideoHeightKey: @(height),
AVVideoCompressionPropertiesKey: @{
AVVideoAverageBitRateKey: @(self.bitrate),
AVVideoMaxKeyFrameIntervalKey: @(30 * 2),
AVVideoProfileLevelKey: AVVideoProfileLevelH264Baseline41,
AVVideoAllowFrameReorderingKey: @NO,
}
};
_writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:settings];
_writerInput.expectsMediaDataInRealTime = YES;
_writer = [AVAssetWriter assetWriterWithURL:url fileType:AVFileTypeQuickTimeMovie error:nil];
[_writer addInput:_writerInput];
}
- (void)finishWithCompletionHandler:(void (^)(void))handler {
if (_writer.status == AVAssetWriterStatusWriting) {
[_writer finishWritingWithCompletionHandler:handler];
}
}
- (BOOL)encodeFrame:(CMSampleBufferRef)sampleBuffer {
if (CMSampleBufferDataIsReady(sampleBuffer)) {
if (_writer.status == AVAssetWriterStatusUnknown) {
CMTime startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
[_writer startWriting];
[_writer startSessionAtSourceTime:startTime];
}
if (_writer.status == AVAssetWriterStatusFailed) {
//NSLog(@"AVAssetWriterStatusFailed");
return NO;
}
if (_writerInput.readyForMoreMediaData == YES) {
[_writerInput appendSampleBuffer:sampleBuffer];
return YES;
}
}
return NO;
}
@end
+5 -3
View File
@@ -2,8 +2,8 @@
// LFAudioEncoding.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -11,6 +11,8 @@
#import "LFAudioFrame.h"
#import "LFLiveAudioConfiguration.h"
@protocol LFAudioEncoding;
/// 编码器编码后回调
@protocol LFAudioEncodingDelegate <NSObject>
@@ -21,7 +23,7 @@
/// 编码器抽象的接口
@protocol LFAudioEncoding <NSObject>
@required
- (void)encodeAudioData:(AudioBufferList)inBufferList timeStamp:(uint64_t)timeStamp;
- (void)encodeAudioData:(nullable NSData*)audioData timeStamp:(uint64_t)timeStamp;
- (void)stopEncoder;
@optional
- (nullable instancetype)initWithAudioStreamConfiguration:(nullable LFLiveAudioConfiguration *)configuration;
+17
View File
@@ -0,0 +1,17 @@
//
// LFH264VideoEncoder
// LFLiveKit
//
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFVideoEncoding.h"
@interface LFH264VideoEncoder : NSObject <LFVideoEncoding> {
}
- (void)shutdown;
@end
+263
View File
@@ -0,0 +1,263 @@
//
// LFH264VideoEncoder
// LFLiveKit
//
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <CoreMedia/CoreMedia.h>
#import <mach/mach_time.h>
#import "LFNALUnit.h"
#import "LFAVEncoder.h"
#import "LFH264VideoEncoder.h"
#import "LFVideoFrame.h"
@interface LFH264VideoEncoder() {
FILE *fp;
NSInteger frameCount;
BOOL enabledWriteVideoFile;
}
@property (nonatomic, strong) LFLiveVideoConfiguration *configuration;
@property (nonatomic, weak) id<LFVideoEncodingDelegate> h264Delegate;
@property (nonatomic) BOOL isBackGround;
@property (nonatomic) NSInteger currentVideoBitRate;
@property (nonatomic, strong) dispatch_queue_t sendQueue;
@property (nonatomic, strong) LFAVEncoder *encoder;
@property (nonatomic, strong) NSData *naluStartCode;
@property (nonatomic, strong) NSMutableData *videoSPSandPPS;
@property (nonatomic, strong) NSMutableData *spsData;
@property (nonatomic, strong) NSMutableData *ppsData;
@property (nonatomic, strong) NSMutableData *sei;
@property (nonatomic) CMTimeScale timescale;
@property (nonatomic, strong) NSMutableArray *orphanedFrames;
@property (nonatomic, strong) NSMutableArray *orphanedSEIFrames;
@property (nonatomic) CMTime lastPTS;
@end
@implementation LFH264VideoEncoder
#pragma mark -- LifeCycle
- (instancetype)initWithVideoStreamConfiguration:(LFLiveVideoConfiguration *)configuration {
if (self = [super init]) {
NSLog(@"USE LF264VideoEncoder");
_configuration = configuration;
[self initCompressionSession];
}
return self;
}
- (void)initCompressionSession{
_sendQueue = dispatch_queue_create("com.youku.laifeng.h264.sendframe", DISPATCH_QUEUE_SERIAL);
[self initializeNALUnitStartCode];
_lastPTS = kCMTimeInvalid;
_timescale = 1000;
frameCount = 0;
#ifdef DEBUG
enabledWriteVideoFile = NO;
[self initForFilePath];
#endif
_encoder = [LFAVEncoder encoderForHeight:(int)_configuration.videoSize.height andWidth:(int)_configuration.videoSize.width bitrate:(int)_configuration.videoBitRate];
[_encoder encodeWithBlock:^int(NSArray* dataArray, CMTimeValue ptsValue) {
[self incomingVideoFrames:dataArray ptsValue:ptsValue];
return 0;
} onParams:^int(NSData *data) {
[self generateSPSandPPS];
return 0;
}];
}
- (void) initializeNALUnitStartCode {
NSUInteger naluLength = 4;
uint8_t *nalu = (uint8_t*)malloc(naluLength * sizeof(uint8_t));
nalu[0] = 0x00;
nalu[1] = 0x00;
nalu[2] = 0x00;
nalu[3] = 0x01;
_naluStartCode = [NSData dataWithBytesNoCopy:nalu length:naluLength freeWhenDone:YES];
}
- (void) generateSPSandPPS {
NSData* config = _encoder.getConfigData;
if (!config) {
return;
}
LFavcCHeader avcC((const BYTE*)[config bytes], (int)[config length]);
LFSeqParamSet seqParams;
seqParams.Parse(avcC.sps());
NSData* spsData = [NSData dataWithBytes:avcC.sps()->Start() length:avcC.sps()->Length()];
NSData *ppsData = [NSData dataWithBytes:avcC.pps()->Start() length:avcC.pps()->Length()];
_spsData = [NSMutableData dataWithCapacity:avcC.sps()->Length()+_naluStartCode.length];
_ppsData = [NSMutableData dataWithCapacity:avcC.pps()->Length()+_naluStartCode.length];
[_spsData appendData:_naluStartCode];
[_spsData appendData:spsData];
[_ppsData appendData:_naluStartCode];
[_ppsData appendData:ppsData];
_videoSPSandPPS = [NSMutableData dataWithCapacity:avcC.sps()->Length() + avcC.pps()->Length() + _naluStartCode.length * 2];
[_videoSPSandPPS appendData:_naluStartCode];
[_videoSPSandPPS appendData:spsData];
[_videoSPSandPPS appendData:_naluStartCode];
[_videoSPSandPPS appendData:ppsData];
}
- (void)setVideoBitRate:(NSInteger)videoBitRate{
_currentVideoBitRate = videoBitRate;
_encoder.bitrate = _currentVideoBitRate;
}
- (NSInteger)videoBitRate{
return _currentVideoBitRate;
}
- (void)setDelegate:(id<LFVideoEncodingDelegate>)delegate{
_h264Delegate = delegate;
}
- (void)encodeVideoData:(CVPixelBufferRef)pixelBuffer timeStamp:(uint64_t)timeStamp {
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
CMVideoFormatDescriptionRef videoInfo = NULL;
CMVideoFormatDescriptionCreateForImageBuffer(NULL, pixelBuffer, &videoInfo);
CMTime frameTime = CMTimeMake(timeStamp, 1000);
CMTime duration = CMTimeMake(1, (int32_t)_configuration.videoFrameRate);
CMSampleTimingInfo timing = {duration, frameTime, kCMTimeInvalid};
CMSampleBufferRef sampleBuffer = NULL;
CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, YES, NULL, NULL, videoInfo, &timing, &sampleBuffer);
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
[_encoder encodeFrame:sampleBuffer];
CFRelease(videoInfo);
CFRelease(sampleBuffer);
frameCount++;
}
- (void)addOrphanedFramesFromArray:(NSArray*)frames {
for (NSData *data in frames) {
unsigned char* pNal = (unsigned char*)[data bytes];
int idc = pNal[0] & 0x60;
int naltype = pNal[0] & 0x1f;
if (idc == 0 && naltype == 6) { // SEI
[self.orphanedSEIFrames addObject:data];
} else {
[self.orphanedFrames addObject:data];
}
}
}
- (void)writeVideoFrames:(NSArray*)frames pts:(CMTime)pts {
NSMutableArray *totalFrames = [NSMutableArray array];
if (self.orphanedSEIFrames.count > 0) {
[totalFrames addObjectsFromArray:self.orphanedSEIFrames];
[self.orphanedSEIFrames removeAllObjects];
}
[totalFrames addObjectsFromArray:frames];
NSMutableData *aggregateFrameData = [NSMutableData data];
//BOOL hasKeyframe = NO;
for (NSData *data in totalFrames) {
unsigned char* pNal = (unsigned char*)[data bytes];
int idc = pNal[0] & 0x60;
int naltype = pNal[0] & 0x1f;
NSData *videoData = nil;
if (idc == 0 && naltype == 6) { // SEI
_sei = [NSMutableData dataWithData:data];
continue;
} else if (naltype == 5) { // IDR
//hasKeyframe = YES;
NSMutableData *IDRData = [NSMutableData dataWithData:_videoSPSandPPS];
if (_sei) {
[IDRData appendData:_naluStartCode];
[IDRData appendData:_sei];
_sei = nil;
}
[IDRData appendData:_naluStartCode];
[IDRData appendData:data];
videoData = IDRData;
} else {
NSMutableData *regularData = [NSMutableData dataWithData:_naluStartCode];
[regularData appendData:data];
videoData = regularData;
}
[aggregateFrameData appendData:videoData];
LFVideoFrame *videoFrame = [LFVideoFrame new];
const char *dataBuffer = (const char *)aggregateFrameData.bytes;
videoFrame.data = [NSMutableData dataWithBytes:dataBuffer + _naluStartCode.length length:aggregateFrameData.length - _naluStartCode.length];
videoFrame.timestamp = pts.value;
videoFrame.isKeyFrame = (naltype == 5);
videoFrame.sps = _spsData;
videoFrame.pps = _ppsData;
if(self.h264Delegate && [self.h264Delegate respondsToSelector:@selector(videoEncoder:videoFrame:)]){
[self.h264Delegate videoEncoder:self videoFrame:videoFrame];
}
}
if (self->enabledWriteVideoFile) {
fwrite(aggregateFrameData.bytes, 1, aggregateFrameData.length, self->fp);
}
}
- (void) incomingVideoFrames:(NSArray*)frames ptsValue:(CMTimeValue)ptsValue {
if (ptsValue == 0) {
[self addOrphanedFramesFromArray:frames];
return;
}
if (!_videoSPSandPPS) {
[self generateSPSandPPS];
}
CMTime pts = CMTimeMake(ptsValue, _timescale);
if (self.orphanedFrames.count > 0) {
CMTime ptsDiff = CMTimeSubtract(pts, _lastPTS);
NSUInteger orphanedFramesCount = self.orphanedFrames.count;
// NSLog(@"lastPTS before first orphaned frame: %lld", _lastPTS.value);
for (NSData *frame in self.orphanedFrames) {
CMTime fakePTSDiff = CMTimeMultiplyByFloat64(ptsDiff, 1.0/(orphanedFramesCount + 1));
CMTime fakePTS = CMTimeAdd(_lastPTS, fakePTSDiff);
// NSLog(@"orphan frame fakePTS: %lld", fakePTS.value);
[self writeVideoFrames:@[frame] pts:fakePTS];
}
// NSLog(@"pts after orphaned frame: %lld", pts.value);
[self.orphanedFrames removeAllObjects];
}
[self writeVideoFrames:frames pts:pts];
_lastPTS = pts;
}
- (void) dealloc {
[_encoder shutdown];
}
- (void)shutdown {
[_encoder encodeWithBlock:nil onParams:nil];
}
- (void)initForFilePath {
NSString *path = [self GetFilePathByfileName:@"IOSCamDemo.h264"];
NSLog(@"%@", path);
self->fp = fopen([path cStringUsingEncoding:NSUTF8StringEncoding], "wb");
}
- (NSString *)GetFilePathByfileName:(NSString*)filename {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:filename];
return writablePath;
}
@end
+2 -2
View File
@@ -2,8 +2,8 @@
// LFHardwareAudioEncoder.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFAudioEncoding.h"
+154 -44
View File
@@ -2,15 +2,19 @@
// LFHardwareAudioEncoder.m
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFHardwareAudioEncoder.h"
@interface LFHardwareAudioEncoder (){
AudioConverterRef m_converter;
char *leftBuf;
char *aacBuf;
NSInteger leftLength;
FILE *fp;
BOOL enabledWriteVideoFile;
}
@property (nonatomic, strong) LFLiveAudioConfiguration *configuration;
@property (nonatomic, weak) id<LFAudioEncodingDelegate> aacDeleage;
@@ -19,15 +23,31 @@
@implementation LFHardwareAudioEncoder
- (instancetype)initWithAudioStreamConfiguration:(LFLiveAudioConfiguration *)configuration {
- (instancetype)initWithAudioStreamConfiguration:(nullable LFLiveAudioConfiguration *)configuration {
if (self = [super init]) {
NSLog(@"USE LFHardwareAudioEncoder");
_configuration = configuration;
if (!leftBuf) {
leftBuf = malloc(_configuration.bufferLength);
}
if (!aacBuf) {
aacBuf = malloc(_configuration.bufferLength);
}
#ifdef DEBUG
enabledWriteVideoFile = NO;
[self initForFilePath];
#endif
}
return self;
}
- (void)dealloc {
if (aacBuf) free(aacBuf);
if (leftBuf) free(leftBuf);
}
#pragma mark -- LFAudioEncoder
@@ -35,29 +55,67 @@
_aacDeleage = delegate;
}
- (void)encodeAudioData:(AudioBufferList)inBufferList timeStamp:(uint64_t)timeStamp {
- (void)encodeAudioData:(nullable NSData*)audioData timeStamp:(uint64_t)timeStamp {
if (![self createAudioConvert]) {
return;
}
if (!aacBuf) {
aacBuf = malloc(inBufferList.mBuffers[0].mDataByteSize);
if(leftLength + audioData.length >= self.configuration.bufferLength){
///<  发送
NSInteger totalSize = leftLength + audioData.length;
NSInteger encodeCount = totalSize/self.configuration.bufferLength;
char *totalBuf = malloc(totalSize);
char *p = totalBuf;
memset(totalBuf, (int)totalSize, 0);
memcpy(totalBuf, leftBuf, leftLength);
memcpy(totalBuf + leftLength, audioData.bytes, audioData.length);
for(NSInteger index = 0;index < encodeCount;index++){
[self encodeBuffer:p timeStamp:timeStamp];
p += self.configuration.bufferLength;
}
leftLength = totalSize%self.configuration.bufferLength;
memset(leftBuf, 0, self.configuration.bufferLength);
memcpy(leftBuf, totalBuf + (totalSize -leftLength), leftLength);
free(totalBuf);
}else{
///< 积累
memcpy(leftBuf+leftLength, audioData.bytes, audioData.length);
leftLength = leftLength + audioData.length;
}
}
- (void)encodeBuffer:(char*)buf timeStamp:(uint64_t)timeStamp{
AudioBuffer inBuffer;
inBuffer.mNumberChannels = 1;
inBuffer.mData = buf;
inBuffer.mDataByteSize = (UInt32)self.configuration.bufferLength;
AudioBufferList buffers;
buffers.mNumberBuffers = 1;
buffers.mBuffers[0] = inBuffer;
// 初始化一个输出缓冲列表
AudioBufferList outBufferList;
outBufferList.mNumberBuffers = 1;
outBufferList.mBuffers[0].mNumberChannels = inBufferList.mBuffers[0].mNumberChannels;
outBufferList.mBuffers[0].mDataByteSize = inBufferList.mBuffers[0].mDataByteSize; // 设置缓冲区大小
outBufferList.mBuffers[0].mNumberChannels = inBuffer.mNumberChannels;
outBufferList.mBuffers[0].mDataByteSize = inBuffer.mDataByteSize; // 设置缓冲区大小
outBufferList.mBuffers[0].mData = aacBuf; // 设置AAC缓冲区
UInt32 outputDataPacketSize = 1;
if (AudioConverterFillComplexBuffer(m_converter, inputDataProc, &inBufferList, &outputDataPacketSize, &outBufferList, NULL) != noErr) {
if (AudioConverterFillComplexBuffer(m_converter, inputDataProc, &buffers, &outputDataPacketSize, &outBufferList, NULL) != noErr) {
return;
}
LFAudioFrame *audioFrame = [LFAudioFrame new];
audioFrame.timestamp = timeStamp;
audioFrame.data = [NSData dataWithBytes:aacBuf length:outBufferList.mBuffers[0].mDataByteSize];
char exeData[2];
exeData[0] = _configuration.asc[0];
exeData[1] = _configuration.asc[1];
@@ -65,10 +123,17 @@
if (self.aacDeleage && [self.aacDeleage respondsToSelector:@selector(audioEncoder:audioFrame:)]) {
[self.aacDeleage audioEncoder:self audioFrame:audioFrame];
}
if (self->enabledWriteVideoFile) {
NSData *adts = [self adtsData:_configuration.numberOfChannels rawDataLength:audioFrame.data.length];
fwrite(adts.bytes, 1, adts.length, self->fp);
fwrite(audioFrame.data.bytes, 1, audioFrame.data.length, self->fp);
}
}
- (void)stopEncoder {
}
#pragma mark -- CustomMethod
@@ -76,7 +141,7 @@
if (m_converter != nil) {
return TRUE;
}
AudioStreamBasicDescription inputFormat = {0};
inputFormat.mSampleRate = _configuration.audioSampleRate;
inputFormat.mFormatID = kAudioFormatLinearPCM;
@@ -86,14 +151,14 @@
inputFormat.mBitsPerChannel = 16;
inputFormat.mBytesPerFrame = inputFormat.mBitsPerChannel / 8 * inputFormat.mChannelsPerFrame;
inputFormat.mBytesPerPacket = inputFormat.mBytesPerFrame * inputFormat.mFramesPerPacket;
AudioStreamBasicDescription outputFormat; // 这里开始是输出音频格式
memset(&outputFormat, 0, sizeof(outputFormat));
outputFormat.mSampleRate = inputFormat.mSampleRate; // 采样率保持一致
outputFormat.mFormatID = kAudioFormatMPEG4AAC; // AAC编码 kAudioFormatMPEG4AAC kAudioFormatMPEG4AAC_HE_V2
outputFormat.mChannelsPerFrame = (UInt32)_configuration.numberOfChannels;;
outputFormat.mFramesPerPacket = 1024; // AAC一帧是1024个字节
const OSType subtype = kAudioFormatMPEG4AAC;
AudioClassDescription requestedCodecs[2] = {
{
@@ -107,37 +172,19 @@
kAppleHardwareAudioCodecManufacturer
}
};
OSStatus result = AudioConverterNewSpecific(&inputFormat, &outputFormat, 2, requestedCodecs, &m_converter);
if (result != noErr) return NO;
OSStatus result = AudioConverterNewSpecific(&inputFormat, &outputFormat, 2, requestedCodecs, &m_converter);;
UInt32 outputBitrate = _configuration.audioBitrate;
UInt32 propSize = sizeof(outputBitrate);
if(result == noErr) {
result = AudioConverterSetProperty(m_converter, kAudioConverterEncodeBitRate, propSize, &outputBitrate);
}
return YES;
}
- (AudioClassDescription *)getAudioClassDescriptionWithType:(UInt32)type fromManufacturer:(UInt32)manufacturer { // 获得相应的编码器
static AudioClassDescription audioDesc;
UInt32 encoderSpecifier = type, size = 0;
OSStatus status;
memset(&audioDesc, 0, sizeof(audioDesc));
status = AudioFormatGetPropertyInfo(kAudioFormatProperty_Encoders, sizeof(encoderSpecifier), &encoderSpecifier, &size);
if (status) {
return nil;
}
uint32_t count = size / sizeof(AudioClassDescription);
AudioClassDescription descs[count];
AudioFormatGetProperty(kAudioFormatProperty_Encoders, sizeof(encoderSpecifier), &encoderSpecifier, &size, descs);
for (uint32_t i = 0; i < count; i++) {
if ((type == descs[i].mSubType) && (manufacturer == descs[i].mManufacturer)) {
memcpy(&audioDesc, &descs[i], sizeof(audioDesc));
break;
}
}
return &audioDesc;
}
#pragma mark -- AudioCallBack
OSStatus inputDataProc(AudioConverterRef inConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription * *outDataPacketDescription, void *inUserData) { //<span style="font-family: Arial, Helvetica, sans-serif;">AudioConverterFillComplexBuffer 编码过程中,会要求这个函数来填充输入数据,也就是原始PCM数据</span>
@@ -148,6 +195,8 @@ OSStatus inputDataProc(AudioConverterRef inConverter, UInt32 *ioNumberDataPacket
return noErr;
}
#pragma mark -- Custom Method
/**
* Add ADTS header at the beginning of each and every AAC packet.
* This is needed as MediaCodec encoder generates a packet of raw
@@ -163,7 +212,7 @@ OSStatus inputDataProc(AudioConverterRef inConverter, UInt32 *ioNumberDataPacket
// Variables Recycled by addADTStoPacket
int profile = 2; //AAC LC
//39=MediaCodecInfo.CodecProfileLevel.AACObjectELD;
int freqIdx = 4; //44.1KHz
NSInteger freqIdx = [self sampleRateIndex:self.configuration.audioSampleRate]; //44.1KHz
int chanCfg = (int)channel; //MPEG-4 Audio Channel Configuration. 1 Channel front-center
NSUInteger fullLength = adtsLength + rawDataLength;
// fill in ADTS data
@@ -178,4 +227,65 @@ OSStatus inputDataProc(AudioConverterRef inConverter, UInt32 *ioNumberDataPacket
return data;
}
- (NSInteger)sampleRateIndex:(NSInteger)frequencyInHz {
NSInteger sampleRateIndex = 0;
switch (frequencyInHz) {
case 96000:
sampleRateIndex = 0;
break;
case 88200:
sampleRateIndex = 1;
break;
case 64000:
sampleRateIndex = 2;
break;
case 48000:
sampleRateIndex = 3;
break;
case 44100:
sampleRateIndex = 4;
break;
case 32000:
sampleRateIndex = 5;
break;
case 24000:
sampleRateIndex = 6;
break;
case 22050:
sampleRateIndex = 7;
break;
case 16000:
sampleRateIndex = 8;
break;
case 12000:
sampleRateIndex = 9;
break;
case 11025:
sampleRateIndex = 10;
break;
case 8000:
sampleRateIndex = 11;
break;
case 7350:
sampleRateIndex = 12;
break;
default:
sampleRateIndex = 15;
}
return sampleRateIndex;
}
- (void)initForFilePath {
NSString *path = [self GetFilePathByfileName:@"IOSCamDemo_HW.aac"];
NSLog(@"%@", path);
self->fp = fopen([path cStringUsingEncoding:NSUTF8StringEncoding], "wb");
}
- (NSString *)GetFilePathByfileName:(NSString*)filename {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:filename];
return writablePath;
}
@end
+2 -2
View File
@@ -2,8 +2,8 @@
// LFHardwareVideoEncoder.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFVideoEncoding.h"
+30 -38
View File
@@ -2,10 +2,9 @@
// LFHardwareVideoEncoder.m
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFHardwareVideoEncoder.h"
#import <VideoToolbox/VideoToolbox.h>
@@ -20,8 +19,8 @@
@property (nonatomic, strong) LFLiveVideoConfiguration *configuration;
@property (nonatomic, weak) id<LFVideoEncodingDelegate> h264Delegate;
@property (nonatomic) BOOL isBackGround;
@property (nonatomic) NSInteger currentVideoBitRate;
@property (nonatomic) BOOL isBackGround;
@end
@@ -30,21 +29,21 @@
#pragma mark -- LifeCycle
- (instancetype)initWithVideoStreamConfiguration:(LFLiveVideoConfiguration *)configuration {
if (self = [super init]) {
NSLog(@"USE LFHardwareVideoEncoder");
_configuration = configuration;
[self initCompressionSession];
[self resetCompressionSession];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterBackground:) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterForeground:) name:UIApplicationDidBecomeActiveNotification object:nil];
#ifdef DEBUG
enabledWriteVideoFile = NO;
[self initForFilePath];
#endif
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterBackground:) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterForeground:) name:UIApplicationDidBecomeActiveNotification object:nil];
}
return self;
}
- (void)initCompressionSession {
- (void)resetCompressionSession {
if (compressionSession) {
VTCompressionSessionCompleteFrames(compressionSession, kCMTimeInvalid);
@@ -60,21 +59,21 @@
_currentVideoBitRate = _configuration.videoBitRate;
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_MaxKeyFrameInterval, (__bridge CFTypeRef)@(_configuration.videoMaxKeyframeInterval));
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, (__bridge CFTypeRef)@(_configuration.videoMaxKeyframeInterval));
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, (__bridge CFTypeRef)@(_configuration.videoMaxKeyframeInterval/_configuration.videoFrameRate));
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_ExpectedFrameRate, (__bridge CFTypeRef)@(_configuration.videoFrameRate));
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_AverageBitRate, (__bridge CFTypeRef)@(_configuration.videoBitRate));
NSArray *limit = @[@(_configuration.videoBitRate * 1.5/8), @(1)];
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_DataRateLimits, (__bridge CFArrayRef)limit);
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_RealTime, kCFBooleanFalse);
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_RealTime, kCFBooleanTrue);
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_ProfileLevel, kVTProfileLevel_H264_Main_AutoLevel);
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_AllowFrameReordering, kCFBooleanFalse);
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_AllowFrameReordering, kCFBooleanTrue);
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_H264EntropyMode, kVTH264EntropyMode_CABAC);
VTCompressionSessionPrepareToEncodeFrames(compressionSession);
}
- (void)setVideoBitRate:(NSInteger)videoBitRate {
if (_isBackGround) return;
if(_isBackGround) return;
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_AverageBitRate, (__bridge CFTypeRef)@(videoBitRate));
NSArray *limit = @[@(videoBitRate * 1.5/8), @(1)];
VTSessionSetProperty(compressionSession, kVTCompressionPropertyKey_DataRateLimits, (__bridge CFArrayRef)limit);
@@ -97,11 +96,10 @@
}
#pragma mark -- LFVideoEncoder
- (void)encodeVideoData:(CVImageBufferRef)pixelBuffer timeStamp:(uint64_t)timeStamp {
if (_isBackGround) return;
- (void)encodeVideoData:(CVPixelBufferRef)pixelBuffer timeStamp:(uint64_t)timeStamp {
if(_isBackGround) return;
frameCount++;
CMTime presentationTimeStamp = CMTimeMake(frameCount, 1000);
CMTime presentationTimeStamp = CMTimeMake(frameCount, (int32_t)_configuration.videoFrameRate);
VTEncodeInfoFlags flags;
CMTime duration = CMTimeMake(1, (int32_t)_configuration.videoFrameRate);
@@ -111,7 +109,10 @@
}
NSNumber *timeNumber = @(timeStamp);
VTCompressionSessionEncodeFrame(compressionSession, pixelBuffer, presentationTimeStamp, duration, (__bridge CFDictionaryRef)properties, (__bridge_retained void *)timeNumber, &flags);
OSStatus status = VTCompressionSessionEncodeFrame(compressionSession, pixelBuffer, presentationTimeStamp, duration, (__bridge CFDictionaryRef)properties, (__bridge_retained void *)timeNumber, &flags);
if(status != noErr){
[self resetCompressionSession];
}
}
- (void)stopEncoder {
@@ -122,13 +123,13 @@
_h264Delegate = delegate;
}
#pragma mark -- NSNotification
- (void)willEnterBackground:(NSNotification *)notification {
#pragma mark -- Notification
- (void)willEnterBackground:(NSNotification*)notification{
_isBackGround = YES;
}
- (void)willEnterForeground:(NSNotification *)notification {
[self initCompressionSession];
- (void)willEnterForeground:(NSNotification*)notification{
[self resetCompressionSession];
_isBackGround = NO;
}
@@ -225,25 +226,16 @@ static void VideoCompressonOutputCallback(void *VTref, void *VTFrameRef, OSStatu
}
- (void)initForFilePath {
char *path = [self GetFilePathByfileName:"IOSCamDemo.h264"];
NSLog(@"%s", path);
self->fp = fopen(path, "wb");
NSString *path = [self GetFilePathByfileName:@"IOSCamDemo.h264"];
NSLog(@"%@", path);
self->fp = fopen([path cStringUsingEncoding:NSUTF8StringEncoding], "wb");
}
- (char *)GetFilePathByfileName:(char *)filename {
- (NSString *)GetFilePathByfileName:(NSString*)filename {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *strName = [NSString stringWithFormat:@"%s", filename];
NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:strName];
NSUInteger len = [writablePath length];
char *filepath = (char *)malloc(sizeof(char) * (len + 1));
[writablePath getCString:filepath maxLength:len + 1 encoding:[NSString defaultCStringEncoding]];
return filepath;
NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:filename];
return writablePath;
}
@end
+4 -5
View File
@@ -2,8 +2,8 @@
// LFVideoEncoding.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -20,12 +20,11 @@
/// 编码器抽象的接口
@protocol LFVideoEncoding <NSObject>
@required
- (void)encodeVideoData:(nullable CVImageBufferRef)pixelBuffer timeStamp:(uint64_t)timeStamp;
- (void)stopEncoder;
- (void)encodeVideoData:(nullable CVPixelBufferRef)pixelBuffer timeStamp:(uint64_t)timeStamp;
@optional
@property (nonatomic, assign) NSInteger videoBitRate;
- (nullable instancetype)initWithVideoStreamConfiguration:(nullable LFLiveVideoConfiguration *)configuration;
- (void)setDelegate:(nullable id<LFVideoEncodingDelegate>)delegate;
- (void)stopEncoder;
@end
@@ -2,8 +2,8 @@
// LFLiveAudioConfiguration.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/1.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -19,14 +19,16 @@ typedef NS_ENUM (NSUInteger, LFLiveAudioBitRate) {
/// 128Kbps 音频码率
LFLiveAudioBitRate_128Kbps = 128000,
/// 默认音频码率,默认为 64Kbps
LFLiveAudioBitRate_Default = LFLiveAudioBitRate_64Kbps
LFLiveAudioBitRate_Default = LFLiveAudioBitRate_96Kbps
};
/// 采样率 (默认44.1Hz iphoneg6以上48Hz)
/// 采样率 (默认44.1Hz)
typedef NS_ENUM (NSUInteger, LFLiveAudioSampleRate){
/// 44.1Hz 采样率
/// 16KHz 采样率
LFLiveAudioSampleRate_16000Hz = 16000,
/// 44.1KHz 采样率
LFLiveAudioSampleRate_44100Hz = 44100,
/// 48Hz 采样率
/// 48KHz 采样率
LFLiveAudioSampleRate_48000Hz = 48000,
/// 默认音频码率,默认为 64Kbps
LFLiveAudioSampleRate_Default = LFLiveAudioSampleRate_44100Hz
@@ -34,16 +36,16 @@ typedef NS_ENUM (NSUInteger, LFLiveAudioSampleRate){
/// Audio Live quality(音频质量)
typedef NS_ENUM (NSUInteger, LFLiveAudioQuality){
/// 高音频质量 audio sample rate: 44MHz(默认44.1Hz iphoneg6以上48Hz), audio bitrate: 32Kbps
/// 高音频质量 audio sample rate: 16KHz audio bitrate: numberOfChannels 1 : 32Kbps 2 : 64Kbps
LFLiveAudioQuality_Low = 0,
/// 高音频质量 audio sample rate: 44MHz(默认44.1Hz iphoneg6以上48Hz), audio bitrate: 64Kbps
/// 高音频质量 audio sample rate: 44KHz audio bitrate: 96Kbps
LFLiveAudioQuality_Medium = 1,
/// 高音频质量 audio sample rate: 44MHz(默认44.1Hz iphoneg6以上48Hz), audio bitrate: 96Kbps
/// 高音频质量 audio sample rate: 44MHz audio bitrate: 128Kbps
LFLiveAudioQuality_High = 2,
/// 高音频质量 audio sample rate: 44MHz(默认44.1Hz iphoneg6以上48Hz), audio bitrate: 128Kbps
/// 高音频质量 audio sample rate: 48MHz, audio bitrate: 128Kbps
LFLiveAudioQuality_VeryHigh = 3,
/// 默认音频质量 audio sample rate: 44MHz(默认44.1Hz iphoneg6以上48Hz), audio bitrate: 64Kbps
LFLiveAudioQuality_Default = LFLiveAudioQuality_Medium
/// 默认音频质量 audio sample rate: 44MHz, audio bitrate: 96Kbps
LFLiveAudioQuality_Default = LFLiveAudioQuality_High
};
@interface LFLiveAudioConfiguration : NSObject<NSCoding, NSCopying>
@@ -65,5 +67,7 @@ typedef NS_ENUM (NSUInteger, LFLiveAudioQuality){
@property (nonatomic, assign) LFLiveAudioBitRate audioBitrate;
/// flv编码音频头 44100 为0x12 0x10
@property (nonatomic, assign, readonly) char *asc;
/// 缓存区长度
@property (nonatomic, assign,readonly) NSUInteger bufferLength;
@end
@@ -2,8 +2,8 @@
// LFLiveAudioConfiguration.m
// LFLiveKit
//
// Created by 倾慕 on 16/5/1.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFLiveAudioConfiguration.h"
@@ -21,24 +21,32 @@
LFLiveAudioConfiguration *audioConfig = [LFLiveAudioConfiguration new];
audioConfig.numberOfChannels = 2;
switch (audioQuality) {
case LFLiveAudioQuality_Default: {
audioConfig.audioBitrate = LFLiveAudioBitRate_64Kbps;
}
break;
case LFLiveAudioQuality_Low: {
audioConfig.audioBitrate = LFLiveAudioBitRate_32Kbps;
audioConfig.audioBitrate = audioConfig.numberOfChannels == 1 ? LFLiveAudioBitRate_32Kbps : LFLiveAudioBitRate_64Kbps;
audioConfig.audioSampleRate = LFLiveAudioSampleRate_16000Hz;
}
case LFLiveAudioQuality_High: {
break;
case LFLiveAudioQuality_Medium: {
audioConfig.audioBitrate = LFLiveAudioBitRate_96Kbps;
audioConfig.audioSampleRate = LFLiveAudioSampleRate_44100Hz;
}
break;
case LFLiveAudioQuality_High: {
audioConfig.audioBitrate = LFLiveAudioBitRate_128Kbps;
audioConfig.audioSampleRate = LFLiveAudioSampleRate_44100Hz;
}
break;
case LFLiveAudioQuality_VeryHigh: {
audioConfig.audioBitrate = LFLiveAudioBitRate_128Kbps;
audioConfig.audioSampleRate = LFLiveAudioSampleRate_48000Hz;
}
break;
default:{
audioConfig.audioBitrate = LFLiveAudioBitRate_96Kbps;
audioConfig.audioSampleRate = LFLiveAudioSampleRate_44100Hz;
}
break;
default:
break;
}
audioConfig.audioSampleRate = [self.class isNewThaniPhone6] ? LFLiveAudioSampleRate_48000Hz : LFLiveAudioSampleRate_44100Hz;
return audioConfig;
}
@@ -58,17 +66,21 @@
- (void)setAudioSampleRate:(LFLiveAudioSampleRate)audioSampleRate {
_audioSampleRate = audioSampleRate;
NSInteger sampleRateIndex = [self sampleRateIndex:audioSampleRate];
self.asc[0] = 0x10 | ((sampleRateIndex>>1) & 0x3);
self.asc[0] = 0x10 | ((sampleRateIndex>>1) & 0x7);
self.asc[1] = ((sampleRateIndex & 0x1)<<7) | ((self.numberOfChannels & 0xF) << 3);
}
- (void)setNumberOfChannels:(NSUInteger)numberOfChannels {
_numberOfChannels = numberOfChannels;
NSInteger sampleRateIndex = [self sampleRateIndex:self.audioSampleRate];
self.asc[0] = 0x10 | ((sampleRateIndex>>1) & 0x3);
self.asc[0] = 0x10 | ((sampleRateIndex>>1) & 0x7);
self.asc[1] = ((sampleRateIndex & 0x1)<<7) | ((numberOfChannels & 0xF) << 3);
}
- (NSUInteger)bufferLength{
return 1024*2*self.numberOfChannels;
}
#pragma mark -- CustomMethod
- (NSInteger)sampleRateIndex:(NSInteger)frequencyInHz {
NSInteger sampleRateIndex = 0;
@@ -118,57 +130,6 @@
return sampleRateIndex;
}
#pragma mark -- DeviceCategory
+ (NSString *)deviceName {
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
}
//@"iPad4,1" on 5th Generation iPad (iPad Air) - Wifi
//@"iPad4,2" on 5th Generation iPad (iPad Air) - Cellular
//@"iPad4,4" on 2nd Generation iPad Mini - Wifi
//@"iPad4,5" on 2nd Generation iPad Mini - Cellular
//@"iPad4,7" on 3rd Generation iPad Mini - Wifi (model A1599)
//@"iPhone7,1" on iPhone 6 Plus
//@"iPhone7,2" on iPhone 6
//@"iPhone8,1" on iPhone 6S
//@"iPhone8,2" on iPhone 6S Plus
+ (BOOL)isNewThaniPhone6 {
NSString *device = [self deviceName];
NSLog(@"device %@", device);
if (device == nil) {
return NO;
}
NSArray *array = [device componentsSeparatedByString:@","];
if (array.count < 2) {
return NO;
}
NSString *model = [array objectAtIndex:0];
NSLog(@"model %@", model);
if ([model hasPrefix:@"iPhone"]) {
NSString *str1 = [model substringFromIndex:[@"iPhone" length]];
NSUInteger num = [str1 integerValue];
NSLog(@"num %lu", (unsigned long)num);
if (num > 7) {
return YES;
}
}
if ([model hasPrefix:@"iPad"]) {
NSString *str1 = [model substringFromIndex:[@"iPad" length]];
NSUInteger num = [str1 integerValue];
if (num > 4) {
return YES;
}
}
return NO;
}
#pragma mark -- Encoder
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:@(self.numberOfChannels) forKey:@"numberOfChannels"];
@@ -2,8 +2,8 @@
// LFLiveVideoConfiguration.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/1.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -51,17 +51,23 @@ typedef NS_ENUM (NSUInteger, LFLiveVideoQuality){
+ (instancetype)defaultConfigurationForQuality:(LFLiveVideoQuality)videoQuality;
/// 视频配置(质量 & 是否是横屏)
+ (instancetype)defaultConfigurationForQuality:(LFLiveVideoQuality)videoQuality landscape:(BOOL)landscape;
+ (instancetype)defaultConfigurationForQuality:(LFLiveVideoQuality)videoQuality outputImageOrientation:(UIInterfaceOrientation)outputImageOrientation;
#pragma mark - Attribute
///=============================================================================
/// @name Attribute
///=============================================================================
/// 视频的分辨率,宽高务必设定为 2 的倍数,否则解码播放时可能出现绿边
/// 视频的分辨率,宽高务必设定为 2 的倍数,否则解码播放时可能出现绿边(这个videoSizeRespectingAspectRatio设置为YES则可能会改变)
@property (nonatomic, assign) CGSize videoSize;
/// 输出图像是否等比例,默认为NO
@property (nonatomic, assign) BOOL videoSizeRespectingAspectRatio;
/// 视频输出方向
@property (nonatomic, assign) BOOL landscape;
@property (nonatomic, assign) UIInterfaceOrientation outputImageOrientation;
/// 自动旋转(这里只支持 left 变 right portrait 变 portraitUpsideDown)
@property (nonatomic, assign) BOOL autorotate;
/// 视频的帧率,即 fps
@property (nonatomic, assign) NSUInteger videoFrameRate;
@@ -90,7 +96,7 @@ typedef NS_ENUM (NSUInteger, LFLiveVideoQuality){
///< ≈sde3分辨率
@property (nonatomic, assign, readonly) NSString *avSessionPreset;
///< 是否裁剪
@property (nonatomic, assign, readonly) BOOL isClipVideo;
///< 是否是横屏
@property (nonatomic, assign, readonly) BOOL landscape;
@end
@@ -2,31 +2,32 @@
// LFLiveVideoConfiguration.m
// LFLiveKit
//
// Created by 倾慕 on 16/5/1.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFLiveVideoConfiguration.h"
#import <AVFoundation/AVFoundation.h>
@implementation LFLiveVideoConfiguration
#pragma mark -- LifeCycle
+ (instancetype)defaultConfiguration {
LFLiveVideoConfiguration *configuration = [LFLiveVideoConfiguration defaultConfigurationForQuality:LFLiveVideoQuality_Default];
return configuration;
}
+ (instancetype)defaultConfigurationForQuality:(LFLiveVideoQuality)videoQuality {
LFLiveVideoConfiguration *configuration = [LFLiveVideoConfiguration defaultConfigurationForQuality:videoQuality landscape:NO];
LFLiveVideoConfiguration *configuration = [LFLiveVideoConfiguration defaultConfigurationForQuality:videoQuality outputImageOrientation:UIInterfaceOrientationPortrait];
return configuration;
}
+ (instancetype)defaultConfigurationForQuality:(LFLiveVideoQuality)videoQuality landscape:(BOOL)landscape {
+ (instancetype)defaultConfigurationForQuality:(LFLiveVideoQuality)videoQuality outputImageOrientation:(UIInterfaceOrientation)outputImageOrientation {
LFLiveVideoConfiguration *configuration = [LFLiveVideoConfiguration new];
switch (videoQuality) {
case LFLiveVideoQuality_Low1:
{
case LFLiveVideoQuality_Low1:{
configuration.sessionPreset = LFCaptureSessionPreset360x640;
configuration.videoFrameRate = 15;
configuration.videoMaxFrameRate = 15;
@@ -36,9 +37,8 @@
configuration.videoMinBitRate = 400 * 1000;
configuration.videoSize = CGSizeMake(360, 640);
}
break;
case LFLiveVideoQuality_Low2:
{
break;
case LFLiveVideoQuality_Low2:{
configuration.sessionPreset = LFCaptureSessionPreset360x640;
configuration.videoFrameRate = 24;
configuration.videoMaxFrameRate = 24;
@@ -48,9 +48,8 @@
configuration.videoMinBitRate = 500 * 1000;
configuration.videoSize = CGSizeMake(360, 640);
}
break;
case LFLiveVideoQuality_Low3:
{
break;
case LFLiveVideoQuality_Low3: {
configuration.sessionPreset = LFCaptureSessionPreset360x640;
configuration.videoFrameRate = 30;
configuration.videoMaxFrameRate = 30;
@@ -60,9 +59,8 @@
configuration.videoMinBitRate = 600 * 1000;
configuration.videoSize = CGSizeMake(360, 640);
}
break;
case LFLiveVideoQuality_Medium1:
{
break;
case LFLiveVideoQuality_Medium1:{
configuration.sessionPreset = LFCaptureSessionPreset540x960;
configuration.videoFrameRate = 15;
configuration.videoMaxFrameRate = 15;
@@ -72,9 +70,8 @@
configuration.videoMinBitRate = 500 * 1000;
configuration.videoSize = CGSizeMake(540, 960);
}
break;
case LFLiveVideoQuality_Medium2:
{
break;
case LFLiveVideoQuality_Medium2:{
configuration.sessionPreset = LFCaptureSessionPreset540x960;
configuration.videoFrameRate = 24;
configuration.videoMaxFrameRate = 24;
@@ -84,9 +81,8 @@
configuration.videoMinBitRate = 500 * 1000;
configuration.videoSize = CGSizeMake(540, 960);
}
break;
case LFLiveVideoQuality_Medium3:
{
break;
case LFLiveVideoQuality_Medium3:{
configuration.sessionPreset = LFCaptureSessionPreset540x960;
configuration.videoFrameRate = 30;
configuration.videoMaxFrameRate = 30;
@@ -96,9 +92,8 @@
configuration.videoMinBitRate = 500 * 1000;
configuration.videoSize = CGSizeMake(540, 960);
}
break;
case LFLiveVideoQuality_High1:
{
break;
case LFLiveVideoQuality_High1:{
configuration.sessionPreset = LFCaptureSessionPreset720x1280;
configuration.videoFrameRate = 15;
configuration.videoMaxFrameRate = 15;
@@ -108,9 +103,8 @@
configuration.videoMinBitRate = 500 * 1000;
configuration.videoSize = CGSizeMake(720, 1280);
}
break;
case LFLiveVideoQuality_High2:
{
break;
case LFLiveVideoQuality_High2:{
configuration.sessionPreset = LFCaptureSessionPreset720x1280;
configuration.videoFrameRate = 24;
configuration.videoMaxFrameRate = 24;
@@ -120,9 +114,8 @@
configuration.videoMinBitRate = 800 * 1000;
configuration.videoSize = CGSizeMake(720, 1280);
}
break;
case LFLiveVideoQuality_High3:
{
break;
case LFLiveVideoQuality_High3:{
configuration.sessionPreset = LFCaptureSessionPreset720x1280;
configuration.videoFrameRate = 30;
configuration.videoMaxFrameRate = 30;
@@ -132,49 +125,58 @@
configuration.videoMinBitRate = 500 * 1000;
configuration.videoSize = CGSizeMake(720, 1280);
}
break;
break;
default:
break;
}
configuration.sessionPreset = [configuration supportSessionPreset:configuration.sessionPreset];
configuration.videoMaxKeyframeInterval = configuration.videoFrameRate*2;
configuration.landscape = landscape;
configuration.outputImageOrientation = outputImageOrientation;
CGSize size = configuration.videoSize;
if (landscape) {
if(configuration.landscape) {
configuration.videoSize = CGSizeMake(size.height, size.width);
} else {
configuration.videoSize = CGSizeMake(size.width, size.height);
}
return configuration;
}
#pragma mark -- Setter Getter
- (NSString *)avSessionPreset {
NSString *avSessionPreset = nil;
switch (self.sessionPreset) {
case LFCaptureSessionPreset360x640:
{
case LFCaptureSessionPreset360x640:{
avSessionPreset = AVCaptureSessionPreset640x480;
}
break;
case LFCaptureSessionPreset540x960:
{
break;
case LFCaptureSessionPreset540x960:{
avSessionPreset = AVCaptureSessionPresetiFrame960x540;
}
break;
case LFCaptureSessionPreset720x1280:
{
break;
case LFCaptureSessionPreset720x1280:{
avSessionPreset = AVCaptureSessionPreset1280x720;
}
break;
break;
default: {
avSessionPreset = AVCaptureSessionPreset640x480;
}
break;
break;
}
return avSessionPreset;
}
- (BOOL)landscape{
return (self.outputImageOrientation == UIInterfaceOrientationLandscapeLeft || self.outputImageOrientation == UIInterfaceOrientationLandscapeRight) ? YES : NO;
}
- (CGSize)videoSize{
if(_videoSizeRespectingAspectRatio){
return self.aspectRatioVideoSize;
}
return _videoSize;
}
- (void)setVideoMaxBitRate:(NSUInteger)videoMaxBitRate {
if (videoMaxBitRate <= _videoBitRate) return;
_videoMaxBitRate = videoMaxBitRate;
@@ -195,15 +197,31 @@
_videoMinFrameRate = videoMinFrameRate;
}
- (void)setSessionPreset:(LFLiveVideoSessionPreset)sessionPreset{
_sessionPreset = sessionPreset;
_sessionPreset = [self supportSessionPreset:sessionPreset];
}
#pragma mark -- Custom Method
- (LFLiveVideoSessionPreset)supportSessionPreset:(LFLiveVideoSessionPreset)sessionPreset {
NSString *avSessionPreset = [self avSessionPreset];
AVCaptureSession *session = [[AVCaptureSession alloc] init];
if (![session canSetSessionPreset:avSessionPreset]) {
AVCaptureDevice *inputCamera;
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices){
if ([device position] == AVCaptureDevicePositionFront){
inputCamera = device;
}
}
AVCaptureDeviceInput *videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:inputCamera error:nil];
if ([session canAddInput:videoInput]){
[session addInput:videoInput];
}
if (![session canSetSessionPreset:self.avSessionPreset]) {
if (sessionPreset == LFCaptureSessionPreset720x1280) {
sessionPreset = LFCaptureSessionPreset540x960;
if (![session canSetSessionPreset:avSessionPreset]) {
if (![session canSetSessionPreset:self.avSessionPreset]) {
sessionPreset = LFCaptureSessionPreset360x640;
}
} else if (sessionPreset == LFCaptureSessionPreset540x960) {
@@ -213,28 +231,73 @@
return sessionPreset;
}
- (BOOL)isClipVideo {
return self.sessionPreset == LFCaptureSessionPreset360x640 ? YES : NO;
- (CGSize)captureOutVideoSize{
CGSize videoSize = CGSizeZero;
switch (_sessionPreset) {
case LFCaptureSessionPreset360x640:{
videoSize = CGSizeMake(360, 640);
}
break;
case LFCaptureSessionPreset540x960:{
videoSize = CGSizeMake(540, 960);
}
break;
case LFCaptureSessionPreset720x1280:{
videoSize = CGSizeMake(720, 1280);
}
break;
default:{
videoSize = CGSizeMake(360, 640);
}
break;
}
if (self.landscape){
return CGSizeMake(videoSize.height, videoSize.width);
}
return videoSize;
}
- (CGSize)aspectRatioVideoSize{
CGSize size = AVMakeRectWithAspectRatioInsideRect(self.captureOutVideoSize, CGRectMake(0, 0, _videoSize.width, _videoSize.height)).size;
NSInteger width = ceil(size.width);
NSInteger height = ceil(size.height);
if(width %2 != 0) width = width - 1;
if(height %2 != 0) height = height - 1;
return CGSizeMake(width, height);
}
#pragma mark -- encoder
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:[NSValue valueWithCGSize:self.videoSize] forKey:@"videoSize"];
[aCoder encodeObject:@(self.videoFrameRate) forKey:@"videoFrameRate"];
[aCoder encodeObject:@(self.videoMaxFrameRate) forKey:@"videoMaxFrameRate"];
[aCoder encodeObject:@(self.videoMinFrameRate) forKey:@"videoMinFrameRate"];
[aCoder encodeObject:@(self.videoMaxKeyframeInterval) forKey:@"videoMaxKeyframeInterval"];
[aCoder encodeObject:@(self.videoBitRate) forKey:@"videoBitRate"];
[aCoder encodeObject:@(self.videoMaxBitRate) forKey:@"videoMaxBitRate"];
[aCoder encodeObject:@(self.videoMinBitRate) forKey:@"videoMinBitRate"];
[aCoder encodeObject:@(self.sessionPreset) forKey:@"sessionPreset"];
[aCoder encodeObject:@(self.landscape) forKey:@"landscape"];
[aCoder encodeObject:@(self.outputImageOrientation) forKey:@"outputImageOrientation"];
[aCoder encodeObject:@(self.autorotate) forKey:@"autorotate"];
[aCoder encodeObject:@(self.videoSizeRespectingAspectRatio) forKey:@"videoSizeRespectingAspectRatio"];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
_videoSize = [[aDecoder decodeObjectForKey:@"videoSize"] CGSizeValue];
_videoFrameRate = [[aDecoder decodeObjectForKey:@"videoFrameRate"] unsignedIntegerValue];
_videoMaxFrameRate = [[aDecoder decodeObjectForKey:@"videoMaxFrameRate"] unsignedIntegerValue];
_videoMinFrameRate = [[aDecoder decodeObjectForKey:@"videoMinFrameRate"] unsignedIntegerValue];
_videoMaxKeyframeInterval = [[aDecoder decodeObjectForKey:@"videoMaxKeyframeInterval"] unsignedIntegerValue];
_videoBitRate = [[aDecoder decodeObjectForKey:@"videoBitRate"] unsignedIntegerValue];
_videoMaxBitRate = [[aDecoder decodeObjectForKey:@"videoMaxBitRate"] unsignedIntegerValue];
_videoMinBitRate = [[aDecoder decodeObjectForKey:@"videoMinBitRate"] unsignedIntegerValue];
_sessionPreset = [[aDecoder decodeObjectForKey:@"sessionPreset"] unsignedIntegerValue];
_landscape = [[aDecoder decodeObjectForKey:@"landscape"] unsignedIntegerValue];
_outputImageOrientation = [[aDecoder decodeObjectForKey:@"outputImageOrientation"] unsignedIntegerValue];
_autorotate = [[aDecoder decodeObjectForKey:@"autorotate"] boolValue];
_videoSizeRespectingAspectRatio = [[aDecoder decodeObjectForKey:@"videoSizeRespectingAspectRatio"] unsignedIntegerValue];
return self;
}
@@ -248,10 +311,11 @@
@(self.videoBitRate),
@(self.videoMaxBitRate),
@(self.videoMinBitRate),
@(self.isClipVideo),
self.avSessionPreset,
@(self.sessionPreset),
@(self.landscape), ];
@(self.outputImageOrientation),
@(self.autorotate),
@(self.videoSizeRespectingAspectRatio)];
for (NSObject *value in values) {
hash ^= value.hash;
@@ -274,10 +338,11 @@
object.videoBitRate == self.videoBitRate &&
object.videoMaxBitRate == self.videoMaxBitRate &&
object.videoMinBitRate == self.videoMinBitRate &&
object.isClipVideo == self.isClipVideo &&
[object.avSessionPreset isEqualToString:self.avSessionPreset] &&
object.sessionPreset == self.sessionPreset &&
object.landscape == self.landscape;
object.outputImageOrientation == self.outputImageOrientation &&
object.autorotate == self.autorotate &&
object.videoSizeRespectingAspectRatio == self.videoSizeRespectingAspectRatio;
}
}
@@ -290,6 +355,7 @@
NSMutableString *desc = @"".mutableCopy;
[desc appendFormat:@"<LFLiveVideoConfiguration: %p>", self];
[desc appendFormat:@" videoSize:%@", NSStringFromCGSize(self.videoSize)];
[desc appendFormat:@" videoSizeRespectingAspectRatio:%zi",self.videoSizeRespectingAspectRatio];
[desc appendFormat:@" videoFrameRate:%zi", self.videoFrameRate];
[desc appendFormat:@" videoMaxFrameRate:%zi", self.videoMaxFrameRate];
[desc appendFormat:@" videoMinFrameRate:%zi", self.videoMinFrameRate];
@@ -297,10 +363,10 @@
[desc appendFormat:@" videoBitRate:%zi", self.videoBitRate];
[desc appendFormat:@" videoMaxBitRate:%zi", self.videoMaxBitRate];
[desc appendFormat:@" videoMinBitRate:%zi", self.videoMinBitRate];
[desc appendFormat:@" isClipVideo:%zi", self.isClipVideo];
[desc appendFormat:@" avSessionPreset:%@", self.avSessionPreset];
[desc appendFormat:@" sessionPreset:%zi", self.sessionPreset];
[desc appendFormat:@" landscape:%zi", self.landscape];
[desc appendFormat:@" outputImageOrientation:%zi", self.outputImageOrientation];
[desc appendFormat:@" autorotate:%zi", self.autorotate];
return desc;
}
+5 -1
View File
@@ -1,4 +1,8 @@
#import "GPUImageFilter.h"
#if __has_include(<GPUImage/GPUImageFramework.h>)
#import <GPUImage/GPUImageFramework.h>
#else
#import "GPUImage.h"
#endif
@interface LFGPUImageBeautyFilter : GPUImageFilter {
}
@@ -238,7 +238,6 @@ NSString *const kLFGPUImageBeautyFragmentShaderString = SHADER_STRING
}
- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex {
CGSize oldInputSize = inputTextureSize;
[super setInputSize:newSize atIndex:textureIndex];
inputTextureSize = newSize;
+5 -1
View File
@@ -1,4 +1,8 @@
#import "GPUImageFilter.h"
#if __has_include(<GPUImage/GPUImageFramework.h>)
#import <GPUImage/GPUImageFramework.h>
#else
#import "GPUImage.h"
#endif
@interface LFGPUImageEmptyFilter : GPUImageFilter
{
+2 -2
View File
@@ -2,8 +2,8 @@
// LFAudioFrame.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFFrame.h"
+2 -2
View File
@@ -2,8 +2,8 @@
// LFAudioFrame.m
// LFLiveKit
//
// Created by on 16/5/2.
// Copyright © 2016 . All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016 LaiFeng All rights reserved.
//
#import "LFAudioFrame.h"
+3 -3
View File
@@ -2,15 +2,15 @@
// LFFrame.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
@interface LFFrame : NSObject
@property (nonatomic, assign) uint64_t timestamp;
@property (nonatomic, assign,) uint64_t timestamp;
@property (nonatomic, strong) NSData *data;
///< flv或者rtmp包头
@property (nonatomic, strong) NSData *header;
+2 -2
View File
@@ -2,8 +2,8 @@
// LFFrame.m
// LFLiveKit
//
// Created by on 16/5/2.
// Copyright © 2016 . All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016 LaiFeng All rights reserved.
//
#import "LFFrame.h"
+2 -2
View File
@@ -2,8 +2,8 @@
// LFLiveDebug.h
// LaiFeng
//
// Created by admin on 16/5/19.
// Copyright © 2016年 live Interactive. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
+2 -2
View File
@@ -2,8 +2,8 @@
// LFLiveDebug.m
// LaiFeng
//
// Created by admin on 16/5/19.
// Copyright © 2016 live Interactive. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016 LaiFeng All rights reserved.
//
#import "LFLiveDebug.h"
+8 -5
View File
@@ -2,14 +2,16 @@
// LFLiveStreamInfo.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// 真正的上传地址 token等
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
#import "LFLiveAudioConfiguration.h"
#import "LFLiveVideoConfiguration.h"
/// 流状态
typedef NS_ENUM (NSUInteger, LFLiveState){
/// 准备
@@ -21,7 +23,9 @@ typedef NS_ENUM (NSUInteger, LFLiveState){
/// 已断开
LFLiveStop = 3,
/// 连接出错
LFLiveError = 4
LFLiveError = 4,
///  正在刷新
LFLiveRefresh = 5
};
typedef NS_ENUM (NSUInteger, LFLiveSocketErrorCode) {
@@ -46,5 +50,4 @@ typedef NS_ENUM (NSUInteger, LFLiveSocketErrorCode) {
///视频配置
@property (nonatomic, strong) LFLiveVideoConfiguration *videoConfiguration;
@end
+2 -2
View File
@@ -2,8 +2,8 @@
// LFLiveStreamInfo.m
// LFLiveKit
//
// Created by on 16/5/2.
// Copyright © 2016 . All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016 LaiFeng All rights reserved.
//
#import "LFLiveStreamInfo.h"
+3 -2
View File
@@ -2,12 +2,13 @@
// LFVideoFrame.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFFrame.h"
@interface LFVideoFrame : LFFrame
@property (nonatomic, assign) BOOL isKeyFrame;
+2 -2
View File
@@ -2,8 +2,8 @@
// LFVideoFrame.m
// LFLiveKit
//
// Created by on 16/5/2.
// Copyright © 2016 . All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016 LaiFeng All rights reserved.
//
#import "LFVideoFrame.h"
+2 -2
View File
@@ -2,8 +2,8 @@
// LFStreamRTMPSocket.h
// LaiFeng
//
// Created by admin on 16/5/18.
// Copyright © 2016年 live Interactive. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import "LFStreamSocket.h"
@@ -2,14 +2,14 @@
// LFStreamRTMPSocket.m
// LFLiveKit
//
// Created by admin on 16/5/18.
// Copyright © 2016 live Interactive. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016 LaiFeng All rights reserved.
//
#import "LFStreamRTMPSocket.h"
#import "rtmp.h"
static const NSInteger RetryTimesBreaken = 20; ///< 1 3 20
static const NSInteger RetryTimesBreaken = 5; ///< 1 3 20
static const NSInteger RetryTimesMargin = 3;
@@ -21,7 +21,7 @@ static const NSInteger RetryTimesMargin = 3;
#define SAVC(x) static const AVal av_ ## x = AVC(#x)
static const AVal av_setDataFrame = AVC("@setDataFrame");
static const AVal av_SDKVersion = AVC("LFLiveKit 1.8.0");
static const AVal av_SDKVersion = AVC("LFLiveKit 2.4.0");
SAVC(onMetaData);
SAVC(duration);
SAVC(width);
@@ -33,10 +33,10 @@ SAVC(audiocodecid);
SAVC(audiodatarate);
SAVC(audiosamplerate);
SAVC(audiosamplesize);
SAVC(audiochannels);
//SAVC(audiochannels);
SAVC(stereo);
SAVC(encoder);
SAVC(av_stereo);
//SAVC(av_stereo);
SAVC(fileSize);
SAVC(avc1);
SAVC(mp4a);
@@ -69,13 +69,17 @@ SAVC(mp4a);
@implementation LFStreamRTMPSocket
#pragma mark -- LFStreamSocket
- (nullable instancetype)initWithStream:(nullable LFLiveStreamInfo *)stream videoSize:(CGSize)videoSize reconnectInterval:(NSInteger)reconnectInterval reconnectCount:(NSInteger)reconnectCount {
- (nullable instancetype)initWithStream:(nullable LFLiveStreamInfo *)stream{
return [self initWithStream:stream reconnectInterval:0 reconnectCount:0];
}
- (nullable instancetype)initWithStream:(nullable LFLiveStreamInfo *)stream reconnectInterval:(NSInteger)reconnectInterval reconnectCount:(NSInteger)reconnectCount{
if (!stream) @throw [NSException exceptionWithName:@"LFStreamRtmpSocket init error" reason:@"stream is nil" userInfo:nil];
if (self = [super init]) {
_stream = stream;
if (reconnectInterval > 0) _reconnectInterval = reconnectInterval;
else _reconnectInterval = RetryTimesMargin;
if (reconnectCount > 0) _reconnectCount = reconnectCount;
else _reconnectCount = RetryTimesBreaken;
@@ -101,12 +105,24 @@ SAVC(mp4a);
self.debugInfo.streamId = self.stream.streamId;
self.debugInfo.uploadUrl = self.stream.url;
self.debugInfo.isRtmp = YES;
if (_isConnecting) return;
_isConnecting = YES;
if (self.delegate && [self.delegate respondsToSelector:@selector(socketStatus:status:)]) {
[self.delegate socketStatus:self status:LFLivePending];
}
if (_rtmp != NULL) {
PILI_RTMP_Close(_rtmp, &_error);
PILI_RTMP_Free(_rtmp);
}
[self RTMP264_Connect:(char *)[_stream.url cStringUsingEncoding:NSASCIIStringEncoding]];
}
- (void)stop {
dispatch_async(self.rtmpSendQueue, ^{
[self _stop];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
});
}
@@ -120,12 +136,12 @@ SAVC(mp4a);
_rtmp = NULL;
}
[self clean];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
- (void)sendFrame:(LFFrame *)frame {
if (!frame) return;
[self.buffer appendObject:frame];
if(!self.isSending){
[self sendFrame];
}
@@ -137,74 +153,75 @@ SAVC(mp4a);
#pragma mark -- CustomMethod
- (void)sendFrame {
__weak typeof(self) _self = self;
dispatch_async(self.rtmpSendQueue, ^{
if (!self.isSending && self.buffer.list.count > 0) {
self.isSending = YES;
if (!_self.isSending && _self.buffer.list.count > 0) {
_self.isSending = YES;
if (!_isConnected || _isReconnecting || _isConnecting || !_rtmp){
self.isSending = NO;
if (!_self.isConnected || _self.isReconnecting || _self.isConnecting || !_rtmp){
_self.isSending = NO;
return;
}
//
LFFrame *frame = [self.buffer popFirstObject];
LFFrame *frame = [_self.buffer popFirstObject];
if ([frame isKindOfClass:[LFVideoFrame class]]) {
if (!self.sendVideoHead) {
self.sendVideoHead = YES;
if (!_self.sendVideoHead) {
_self.sendVideoHead = YES;
if(!((LFVideoFrame*)frame).sps || !((LFVideoFrame*)frame).pps){
self.isSending = NO;
_self.isSending = NO;
return;
}
[self sendVideoHeader:(LFVideoFrame *)frame];
[_self sendVideoHeader:(LFVideoFrame *)frame];
} else {
[self sendVideo:(LFVideoFrame *)frame];
[_self sendVideo:(LFVideoFrame *)frame];
}
} else {
if (!self.sendAudioHead) {
self.sendAudioHead = YES;
if (!_self.sendAudioHead) {
_self.sendAudioHead = YES;
if(!((LFAudioFrame*)frame).audioInfo){
self.isSending = NO;
_self.isSending = NO;
return;
}
[self sendAudioHeader:(LFAudioFrame *)frame];
[_self sendAudioHeader:(LFAudioFrame *)frame];
} else {
[self sendAudio:frame];
[_self sendAudio:frame];
}
}
//debug更新
self.debugInfo.totalFrame++;
self.debugInfo.dropFrame += self.buffer.lastDropFrames;
self.buffer.lastDropFrames = 0;
_self.debugInfo.totalFrame++;
_self.debugInfo.dropFrame += _self.buffer.lastDropFrames;
_self.buffer.lastDropFrames = 0;
self.debugInfo.dataFlow += frame.data.length;
self.debugInfo.elapsedMilli = CACurrentMediaTime() * 1000 - self.debugInfo.timeStamp;
if (self.debugInfo.elapsedMilli < 1000) {
self.debugInfo.bandwidth += frame.data.length;
_self.debugInfo.dataFlow += frame.data.length;
_self.debugInfo.elapsedMilli = CACurrentMediaTime() * 1000 - _self.debugInfo.timeStamp;
if (_self.debugInfo.elapsedMilli < 1000) {
_self.debugInfo.bandwidth += frame.data.length;
if ([frame isKindOfClass:[LFAudioFrame class]]) {
self.debugInfo.capturedAudioCount++;
_self.debugInfo.capturedAudioCount++;
} else {
self.debugInfo.capturedVideoCount++;
_self.debugInfo.capturedVideoCount++;
}
self.debugInfo.unSendCount = self.buffer.list.count;
_self.debugInfo.unSendCount = _self.buffer.list.count;
} else {
self.debugInfo.currentBandwidth = self.debugInfo.bandwidth;
self.debugInfo.currentCapturedAudioCount = self.debugInfo.capturedAudioCount;
self.debugInfo.currentCapturedVideoCount = self.debugInfo.capturedVideoCount;
if (self.delegate && [self.delegate respondsToSelector:@selector(socketDebug:debugInfo:)]) {
[self.delegate socketDebug:self debugInfo:self.debugInfo];
_self.debugInfo.currentBandwidth = _self.debugInfo.bandwidth;
_self.debugInfo.currentCapturedAudioCount = _self.debugInfo.capturedAudioCount;
_self.debugInfo.currentCapturedVideoCount = _self.debugInfo.capturedVideoCount;
if (_self.delegate && [_self.delegate respondsToSelector:@selector(socketDebug:debugInfo:)]) {
[_self.delegate socketDebug:_self debugInfo:_self.debugInfo];
}
self.debugInfo.bandwidth = 0;
self.debugInfo.capturedAudioCount = 0;
self.debugInfo.capturedVideoCount = 0;
self.debugInfo.timeStamp = CACurrentMediaTime() * 1000;
_self.debugInfo.bandwidth = 0;
_self.debugInfo.capturedAudioCount = 0;
_self.debugInfo.capturedVideoCount = 0;
_self.debugInfo.timeStamp = CACurrentMediaTime() * 1000;
}
//
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//< sendFrame方法
self.isSending = NO;
_self.isSending = NO;
});
}
@@ -226,18 +243,6 @@ SAVC(mp4a);
- (NSInteger)RTMP264_Connect:(char *)push_url {
//timestamp是一直在累加
//
if (_isConnecting) return -1;
_isConnecting = YES;
if (self.delegate && [self.delegate respondsToSelector:@selector(socketStatus:status:)]) {
[self.delegate socketStatus:self status:LFLivePending];
}
if (_rtmp != NULL) {
PILI_RTMP_Close(_rtmp, &_error);
PILI_RTMP_Free(_rtmp);
}
_rtmp = PILI_RTMP_Alloc();
PILI_RTMP_Init(_rtmp);
@@ -252,6 +257,7 @@ SAVC(mp4a);
_rtmp->m_userData = (__bridge void *)self;
_rtmp->m_msgCounter = 1;
_rtmp->Link.timeout = RTMP_RECEIVE_TIMEOUT;
//使
PILI_RTMP_EnableWrite(_rtmp);
@@ -275,19 +281,13 @@ SAVC(mp4a);
_isConnecting = NO;
_isReconnecting = NO;
_isSending = NO;
_retryTimes4netWorkBreaken = 0;
return 0;
Failed:
PILI_RTMP_Close(_rtmp, &_error);
PILI_RTMP_Free(_rtmp);
_rtmp = NULL;
if (self.delegate && [self.delegate respondsToSelector:@selector(socketDidError:errorCode:)]) {
[self.delegate socketDidError:self errorCode:LFLiveSocketError_ConnectSocket];
}
if (self.delegate && [self.delegate respondsToSelector:@selector(socketStatus:status:)]) {
[self.delegate socketStatus:self status:LFLiveError];
}
[self reconnect];
return -1;
}
@@ -340,7 +340,7 @@ Failed:
*enc++ = 0;
*enc++ = AMF_OBJECT_END;
packet.m_nBodySize = enc - packet.m_body;
packet.m_nBodySize = (uint32_t)(enc - packet.m_body);
if (!PILI_RTMP_SendPacket(_rtmp, &packet, FALSE, &_error)) {
return;
}
@@ -479,36 +479,61 @@ Failed:
// 线
- (void)reconnect {
dispatch_async(self.rtmpSendQueue, ^{
_isReconnecting = NO;
if (_isConnected) return;
[self _stop];
[self _start];
if (self.retryTimes4netWorkBreaken++ < self.reconnectCount && !self.isReconnecting) {
self.isConnected = NO;
self.isConnecting = NO;
self.isReconnecting = YES;
dispatch_async(dispatch_get_main_queue(), ^{
[self performSelector:@selector(_reconnect) withObject:nil afterDelay:self.reconnectInterval];
});
} else if (self.retryTimes4netWorkBreaken >= self.reconnectCount) {
if (self.delegate && [self.delegate respondsToSelector:@selector(socketStatus:status:)]) {
[self.delegate socketStatus:self status:LFLiveError];
}
if (self.delegate && [self.delegate respondsToSelector:@selector(socketDidError:errorCode:)]) {
[self.delegate socketDidError:self errorCode:LFLiveSocketError_ReConnectTimeOut];
}
}
});
}
- (void)_reconnect{
[NSObject cancelPreviousPerformRequestsWithTarget:self];
_isReconnecting = NO;
if(_isConnected) return;
_isReconnecting = NO;
if (_isConnected) return;
if (_rtmp != NULL) {
PILI_RTMP_Close(_rtmp, &_error);
PILI_RTMP_Free(_rtmp);
_rtmp = NULL;
}
_sendAudioHead = NO;
_sendVideoHead = NO;
if (self.delegate && [self.delegate respondsToSelector:@selector(socketStatus:status:)]) {
[self.delegate socketStatus:self status:LFLiveRefresh];
}
if (_rtmp != NULL) {
PILI_RTMP_Close(_rtmp, &_error);
PILI_RTMP_Free(_rtmp);
}
[self RTMP264_Connect:(char *)[_stream.url cStringUsingEncoding:NSASCIIStringEncoding]];
}
#pragma mark -- CallBack
void RTMPErrorCallback(RTMPError *error, void *userData) {
LFStreamRTMPSocket *socket = (__bridge LFStreamRTMPSocket *)userData;
if (error->code < 0) {
if (socket.retryTimes4netWorkBreaken++ < socket.reconnectCount && !socket.isReconnecting) {
socket.isConnected = NO;
socket.isConnecting = NO;
socket.isReconnecting = YES;
[socket performSelectorOnMainThread:@selector(reconnect) withObject:nil waitUntilDone:socket.reconnectInterval];
} else if (socket.retryTimes4netWorkBreaken >= socket.reconnectCount) {
if (socket.delegate && [socket.delegate respondsToSelector:@selector(socketStatus:status:)]) {
[socket.delegate socketStatus:socket status:LFLiveError];
}
if (socket.delegate && [socket.delegate respondsToSelector:@selector(socketDidError:errorCode:)]) {
[socket.delegate socketDidError:socket errorCode:LFLiveSocketError_ReConnectTimeOut];
}
}
[socket reconnect];
}
}
void ConnectionTimeCallback(PILI_CONNECTION_TIME *conn_time, void *userData) {
//LFStreamRTMPSocket *socket = (__bridge LFStreamRTMPSocket*)userData;
}
#pragma mark -- LFStreamingBufferDelegate
@@ -533,6 +558,7 @@ void ConnectionTimeCallback(PILI_CONNECTION_TIME *conn_time, void *userData) {
if (!_buffer) {
_buffer = [[LFStreamingBuffer alloc] init];
_buffer.delegate = self;
}
return _buffer;
}
+5 -4
View File
@@ -2,8 +2,8 @@
// LFStreamSocket.h
// LFLiveKit
//
// Created by admin on 16/5/3.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -11,6 +11,8 @@
#import "LFStreamingBuffer.h"
#import "LFLiveDebug.h"
@protocol LFStreamSocket;
@protocol LFStreamSocketDelegate <NSObject>
@@ -32,6 +34,5 @@
- (void)setDelegate:(nullable id <LFStreamSocketDelegate>)delegate;
@optional
- (nullable instancetype)initWithStream:(nullable LFLiveStreamInfo *)stream;
- (nullable instancetype)initWithStream:(nullable LFLiveStreamInfo *)stream videoSize:(CGSize)videoSize;
- (nullable instancetype)initWithStream:(nullable LFLiveStreamInfo *)stream videoSize:(CGSize)videoSize reconnectInterval:(NSInteger)reconnectInterval reconnectCount:(NSInteger)reconnectCount;
- (nullable instancetype)initWithStream:(nullable LFLiveStreamInfo *)stream reconnectInterval:(NSInteger)reconnectInterval reconnectCount:(NSInteger)reconnectCount;
@end
+4 -2
View File
@@ -2,14 +2,15 @@
// LFStreamingBuffer.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
#import "LFAudioFrame.h"
#import "LFVideoFrame.h"
/** current buffer status */
typedef NS_ENUM (NSUInteger, LFLiveBuffferState) {
LFLiveBuffferUnknown = 0, //< 未知
@@ -27,6 +28,7 @@ typedef NS_ENUM (NSUInteger, LFLiveBuffferState) {
@interface LFStreamingBuffer : NSObject
/** The delegate of the buffer. buffer callback */
@property (nullable, nonatomic, weak) id <LFStreamingBufferDelegate> delegate;
+10 -10
View File
@@ -2,14 +2,14 @@
// LFStreamingBuffer.m
// LFLiveKit
//
// Created by on 16/5/2.
// Copyright © 2016 . All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016 LaiFeng All rights reserved.
//
#import "LFStreamingBuffer.h"
#import "NSMutableArray+LFAdd.h"
static const NSUInteger defaultSortBufferMaxCount = 10;///< 10
static const NSUInteger defaultSortBufferMaxCount = 5;///< 10
static const NSUInteger defaultUpdateInterval = 1;///< 1s
static const NSUInteger defaultCallBackInterval = 5;///< 5s计时一次
static const NSUInteger defaultSendBufferMaxCount = 600;///< 600
@@ -97,14 +97,14 @@ static const NSUInteger defaultSendBufferMaxCount = 600;///< 最大缓冲区为6
[self.list removeObjectsInArray:pFrames];
return;
}
NSArray *iFrames = [self expireIFrames];///<  I帧I帧可能对应多个nal
self.lastDropFrames += [iFrames count];
if (iFrames) {
[self.list removeObjectsInArray:iFrames];
return;
}
[self.list removeAllObjects];
}
@@ -155,9 +155,9 @@ NSInteger frameDataCompare(id obj1, id obj2, void *context){
NSInteger decreaseCount = 0;
for (NSNumber *number in self.thresholdList) {
if (number.integerValue >= currentCount) {
if (number.integerValue > currentCount) {
increaseCount++;
} else {
} else{
decreaseCount++;
}
currentCount = [number integerValue];
@@ -170,7 +170,7 @@ NSInteger frameDataCompare(id obj1, id obj2, void *context){
if (decreaseCount >= self.callBackInterval) {
return LFLiveBuffferDecline;
}
return LFLiveBuffferUnknown;
}
@@ -204,7 +204,7 @@ NSInteger frameDataCompare(id obj1, id obj2, void *context){
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
[self.thresholdList addObject:@(self.list.count)];
dispatch_semaphore_signal(_lock);
if (self.currentInterval >= self.callBackInterval) {
LFLiveBuffferState state = [self currentBufferState];
if (state == LFLiveBuffferIncrease) {
@@ -222,7 +222,7 @@ NSInteger frameDataCompare(id obj1, id obj2, void *context){
}
__weak typeof(self) _self = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.updateInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
__weak typeof(_self) self = _self;
__strong typeof(_self) self = _self;
[self tick];
});
}
+2 -2
View File
@@ -2,8 +2,8 @@
// NSMutableArray+LFAdd.h
// YYKit
//
// Created by admin on 16/5/20.
// Copyright © 2016年 倾慕. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
+2 -2
View File
@@ -2,8 +2,8 @@
// NSMutableArray+LFAdd.m
// YYKit
//
// Created by admin on 16/5/20.
// Copyright © 2016 . All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016 LaiFeng All rights reserved.
//
#import "NSMutableArray+LFAdd.h"
-4
View File
@@ -1,4 +0,0 @@
#CocoaPods
Pods/
Podfile.lock
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:LFLiveKitDemo.xcodeproj">
</FileRef>
</Workspace>
@@ -1,111 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "840762EB1D07C7D0000FD0BF"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "840763041D07C7D0000FD0BF"
BuildableName = "LFLiveKitDemoTests.xctest"
BlueprintName = "LFLiveKitDemoTests"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8407630F1D07C7D0000FD0BF"
BuildableName = "LFLiveKitDemoUITests.xctest"
BlueprintName = "LFLiveKitDemoUITests"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "840762EB1D07C7D0000FD0BF"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "840762EB1D07C7D0000FD0BF"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "840762EB1D07C7D0000FD0BF"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -1,37 +0,0 @@
<?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>SchemeUserState</key>
<dict>
<key>LFLiveKitDemo.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>840762EB1D07C7D0000FD0BF</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>840763041D07C7D0000FD0BF</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>8407630F1D07C7D0000FD0BF</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>B2D23E791D348F3D00B34CA8</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
@@ -1,22 +0,0 @@
<?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>SchemeUserState</key>
<dict>
<key>LFLiveKitDemo.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>5</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>B2D23E791D348F3D00B34CA8</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:LFLiveKitDemo.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "0"
version = "2.0">
</Bucket>
-10
View File
@@ -1,10 +0,0 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios,'8.0'
target 'LFLiveKitDemo' do
end
pod 'LFLiveKit', path: '../'
-4
View File
@@ -1,4 +0,0 @@
#CocoaPods
Pods/
Podfile.lock
@@ -1,404 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
B289F1BE1D3DCD3000D9C7A5 /* camra_beauty@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B289F1B61D3DCD3000D9C7A5 /* camra_beauty@2x.png */; };
B289F1BF1D3DCD3000D9C7A5 /* camra_beauty@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B289F1B71D3DCD3000D9C7A5 /* camra_beauty@3x.png */; };
B289F1C01D3DCD3000D9C7A5 /* camra_beauty_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B289F1B81D3DCD3000D9C7A5 /* camra_beauty_close@2x.png */; };
B289F1C11D3DCD3000D9C7A5 /* camra_beauty_close@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B289F1B91D3DCD3000D9C7A5 /* camra_beauty_close@3x.png */; };
B289F1C21D3DCD3000D9C7A5 /* camra_preview@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B289F1BA1D3DCD3000D9C7A5 /* camra_preview@2x.png */; };
B289F1C31D3DCD3000D9C7A5 /* camra_preview@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B289F1BB1D3DCD3000D9C7A5 /* camra_preview@3x.png */; };
B289F1C41D3DCD3000D9C7A5 /* close_preview@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B289F1BC1D3DCD3000D9C7A5 /* close_preview@2x.png */; };
B289F1C51D3DCD3000D9C7A5 /* close_preview@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B289F1BD1D3DCD3000D9C7A5 /* close_preview@3x.png */; };
B2C8FAC51D3DB8B3008D44B5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2C8FAC41D3DB8B3008D44B5 /* AppDelegate.swift */; };
B2C8FAC71D3DB8B3008D44B5 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2C8FAC61D3DB8B3008D44B5 /* ViewController.swift */; };
B2C8FACA1D3DB8B3008D44B5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B2C8FAC81D3DB8B3008D44B5 /* Main.storyboard */; };
B2C8FACC1D3DB8B3008D44B5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B2C8FACB1D3DB8B3008D44B5 /* Assets.xcassets */; };
B2C8FACF1D3DB8B4008D44B5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B2C8FACD1D3DB8B4008D44B5 /* LaunchScreen.storyboard */; };
D76381970CDF6883DA800952 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C703895C713844AE5F37BC53 /* libPods.a */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
B289F1B61D3DCD3000D9C7A5 /* camra_beauty@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty@2x.png"; sourceTree = "<group>"; };
B289F1B71D3DCD3000D9C7A5 /* camra_beauty@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty@3x.png"; sourceTree = "<group>"; };
B289F1B81D3DCD3000D9C7A5 /* camra_beauty_close@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty_close@2x.png"; sourceTree = "<group>"; };
B289F1B91D3DCD3000D9C7A5 /* camra_beauty_close@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty_close@3x.png"; sourceTree = "<group>"; };
B289F1BA1D3DCD3000D9C7A5 /* camra_preview@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_preview@2x.png"; sourceTree = "<group>"; };
B289F1BB1D3DCD3000D9C7A5 /* camra_preview@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_preview@3x.png"; sourceTree = "<group>"; };
B289F1BC1D3DCD3000D9C7A5 /* close_preview@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "close_preview@2x.png"; sourceTree = "<group>"; };
B289F1BD1D3DCD3000D9C7A5 /* close_preview@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "close_preview@3x.png"; sourceTree = "<group>"; };
B2C8FAC11D3DB8B3008D44B5 /* LFLiveKitSwiftDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LFLiveKitSwiftDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
B2C8FAC41D3DB8B3008D44B5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
B2C8FAC61D3DB8B3008D44B5 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
B2C8FAC91D3DB8B3008D44B5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
B2C8FACB1D3DB8B3008D44B5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
B2C8FACE1D3DB8B4008D44B5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
B2C8FAD01D3DB8B4008D44B5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B2C8FAD61D3DB9D6008D44B5 /* LFLiveKitSwiftDemo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LFLiveKitSwiftDemo-Bridging-Header.h"; sourceTree = "<group>"; };
C5E86117C8AB61338C12909E /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
C703895C713844AE5F37BC53 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
FD5AE5787FDCE4BA8C28E2EE /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
B2C8FABE1D3DB8B3008D44B5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D76381970CDF6883DA800952 /* libPods.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0044BAB3BCE83EE63FB6F37C /* Pods */ = {
isa = PBXGroup;
children = (
FD5AE5787FDCE4BA8C28E2EE /* Pods.debug.xcconfig */,
C5E86117C8AB61338C12909E /* Pods.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
656DB83DA3620FA72C6B7CF7 /* Frameworks */ = {
isa = PBXGroup;
children = (
C703895C713844AE5F37BC53 /* libPods.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
B289F1B51D3DCD3000D9C7A5 /* images */ = {
isa = PBXGroup;
children = (
B289F1B61D3DCD3000D9C7A5 /* camra_beauty@2x.png */,
B289F1B71D3DCD3000D9C7A5 /* camra_beauty@3x.png */,
B289F1B81D3DCD3000D9C7A5 /* camra_beauty_close@2x.png */,
B289F1B91D3DCD3000D9C7A5 /* camra_beauty_close@3x.png */,
B289F1BA1D3DCD3000D9C7A5 /* camra_preview@2x.png */,
B289F1BB1D3DCD3000D9C7A5 /* camra_preview@3x.png */,
B289F1BC1D3DCD3000D9C7A5 /* close_preview@2x.png */,
B289F1BD1D3DCD3000D9C7A5 /* close_preview@3x.png */,
);
path = images;
sourceTree = "<group>";
};
B2C8FAB81D3DB8B3008D44B5 = {
isa = PBXGroup;
children = (
B2C8FAC31D3DB8B3008D44B5 /* LFLiveKitSwiftDemo */,
B2C8FAC21D3DB8B3008D44B5 /* Products */,
0044BAB3BCE83EE63FB6F37C /* Pods */,
656DB83DA3620FA72C6B7CF7 /* Frameworks */,
);
sourceTree = "<group>";
};
B2C8FAC21D3DB8B3008D44B5 /* Products */ = {
isa = PBXGroup;
children = (
B2C8FAC11D3DB8B3008D44B5 /* LFLiveKitSwiftDemo.app */,
);
name = Products;
sourceTree = "<group>";
};
B2C8FAC31D3DB8B3008D44B5 /* LFLiveKitSwiftDemo */ = {
isa = PBXGroup;
children = (
B289F1B51D3DCD3000D9C7A5 /* images */,
B2C8FAC41D3DB8B3008D44B5 /* AppDelegate.swift */,
B2C8FAC61D3DB8B3008D44B5 /* ViewController.swift */,
B2C8FAC81D3DB8B3008D44B5 /* Main.storyboard */,
B2C8FAD61D3DB9D6008D44B5 /* LFLiveKitSwiftDemo-Bridging-Header.h */,
B2C8FACB1D3DB8B3008D44B5 /* Assets.xcassets */,
B2C8FACD1D3DB8B4008D44B5 /* LaunchScreen.storyboard */,
B2C8FAD01D3DB8B4008D44B5 /* Info.plist */,
);
path = LFLiveKitSwiftDemo;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
B2C8FAC01D3DB8B3008D44B5 /* LFLiveKitSwiftDemo */ = {
isa = PBXNativeTarget;
buildConfigurationList = B2C8FAD31D3DB8B4008D44B5 /* Build configuration list for PBXNativeTarget "LFLiveKitSwiftDemo" */;
buildPhases = (
BAC96C6840291F2B616FE902 /* Check Pods Manifest.lock */,
B2C8FABD1D3DB8B3008D44B5 /* Sources */,
B2C8FABE1D3DB8B3008D44B5 /* Frameworks */,
B2C8FABF1D3DB8B3008D44B5 /* Resources */,
7490D167BE18C3C7DC2FE381 /* Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = LFLiveKitSwiftDemo;
productName = LFLiveKitSwiftDemo;
productReference = B2C8FAC11D3DB8B3008D44B5 /* LFLiveKitSwiftDemo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
B2C8FAB91D3DB8B3008D44B5 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = zhanqi.tv;
TargetAttributes = {
B2C8FAC01D3DB8B3008D44B5 = {
CreatedOnToolsVersion = 7.3;
};
};
};
buildConfigurationList = B2C8FABC1D3DB8B3008D44B5 /* Build configuration list for PBXProject "LFLiveKitSwiftDemo" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = B2C8FAB81D3DB8B3008D44B5;
productRefGroup = B2C8FAC21D3DB8B3008D44B5 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
B2C8FAC01D3DB8B3008D44B5 /* LFLiveKitSwiftDemo */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
B2C8FABF1D3DB8B3008D44B5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B289F1C01D3DCD3000D9C7A5 /* camra_beauty_close@2x.png in Resources */,
B2C8FACF1D3DB8B4008D44B5 /* LaunchScreen.storyboard in Resources */,
B289F1BE1D3DCD3000D9C7A5 /* camra_beauty@2x.png in Resources */,
B2C8FACC1D3DB8B3008D44B5 /* Assets.xcassets in Resources */,
B289F1C31D3DCD3000D9C7A5 /* camra_preview@3x.png in Resources */,
B289F1C11D3DCD3000D9C7A5 /* camra_beauty_close@3x.png in Resources */,
B289F1C51D3DCD3000D9C7A5 /* close_preview@3x.png in Resources */,
B289F1C41D3DCD3000D9C7A5 /* close_preview@2x.png in Resources */,
B2C8FACA1D3DB8B3008D44B5 /* Main.storyboard in Resources */,
B289F1C21D3DCD3000D9C7A5 /* camra_preview@2x.png in Resources */,
B289F1BF1D3DCD3000D9C7A5 /* camra_beauty@3x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
7490D167BE18C3C7DC2FE381 /* Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
showEnvVarsInLog = 0;
};
BAC96C6840291F2B616FE902 /* Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
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";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
B2C8FABD1D3DB8B3008D44B5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B2C8FAC71D3DB8B3008D44B5 /* ViewController.swift in Sources */,
B2C8FAC51D3DB8B3008D44B5 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
B2C8FAC81D3DB8B3008D44B5 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
B2C8FAC91D3DB8B3008D44B5 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
B2C8FACD1D3DB8B4008D44B5 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
B2C8FACE1D3DB8B4008D44B5 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
B2C8FAD11D3DB8B4008D44B5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
B2C8FAD21D3DB8B4008D44B5 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
B2C8FAD41D3DB8B4008D44B5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FD5AE5787FDCE4BA8C28E2EE /* Pods.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
INFOPLIST_FILE = LFLiveKitSwiftDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.gameabc.laifeng.LFLiveKitSwiftDemo.LFLiveKitSwiftDemo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "LFLiveKitSwiftDemo/LFLiveKitSwiftDemo-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
B2C8FAD51D3DB8B4008D44B5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C5E86117C8AB61338C12909E /* Pods.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
INFOPLIST_FILE = LFLiveKitSwiftDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.gameabc.laifeng.LFLiveKitSwiftDemo.LFLiveKitSwiftDemo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "LFLiveKitSwiftDemo/LFLiveKitSwiftDemo-Bridging-Header.h";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
B2C8FABC1D3DB8B3008D44B5 /* Build configuration list for PBXProject "LFLiveKitSwiftDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B2C8FAD11D3DB8B4008D44B5 /* Debug */,
B2C8FAD21D3DB8B4008D44B5 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B2C8FAD31D3DB8B4008D44B5 /* Build configuration list for PBXNativeTarget "LFLiveKitSwiftDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B2C8FAD41D3DB8B4008D44B5 /* Debug */,
B2C8FAD51D3DB8B4008D44B5 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = B2C8FAB91D3DB8B3008D44B5 /* Project object */;
}
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:LFLiveKitSwiftDemo.xcodeproj">
</FileRef>
</Workspace>
@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B2C8FAC01D3DB8B3008D44B5"
BuildableName = "LFLiveKitSwiftDemo.app"
BlueprintName = "LFLiveKitSwiftDemo"
ReferencedContainer = "container:LFLiveKitSwiftDemo.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B2C8FAC01D3DB8B3008D44B5"
BuildableName = "LFLiveKitSwiftDemo.app"
BlueprintName = "LFLiveKitSwiftDemo"
ReferencedContainer = "container:LFLiveKitSwiftDemo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B2C8FAC01D3DB8B3008D44B5"
BuildableName = "LFLiveKitSwiftDemo.app"
BlueprintName = "LFLiveKitSwiftDemo"
ReferencedContainer = "container:LFLiveKitSwiftDemo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B2C8FAC01D3DB8B3008D44B5"
BuildableName = "LFLiveKitSwiftDemo.app"
BlueprintName = "LFLiveKitSwiftDemo"
ReferencedContainer = "container:LFLiveKitSwiftDemo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -1,22 +0,0 @@
<?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>SchemeUserState</key>
<dict>
<key>LFLiveKitSwiftDemo.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>B2C8FAC01D3DB8B3008D44B5</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:LFLiveKitSwiftDemo.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "0"
version = "2.0">
</Bucket>
@@ -1,10 +0,0 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#ifndef LFLiveKitSwiftDemo_Bridging_H
#define LFLiveKitSwiftDemo_Bridging_H
#import <LFLiveKit.h>
#endif
-4
View File
@@ -1,4 +0,0 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios,'8.0'
pod 'LFLiveKit', path: '../'
-39
View File
@@ -1,39 +0,0 @@
//
// LFLiveKitTests.m
// LFLiveKitTests
//
// Created by admin on 16/6/2.
// Copyright © 2016 admin. All rights reserved.
//
#import <XCTest/XCTest.h>
@interface LFLiveKitTests : XCTestCase
@end
@implementation LFLiveKitTests
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
@end
-10
View File
@@ -1,10 +0,0 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios,'8.0'
target 'LFLiveKit' do
end
pod 'pili-librtmp', '~> 1.0.3'
pod 'LMGPUImage', '~> 0.1.9'
+59 -31
View File
@@ -1,11 +1,14 @@
LFLiveKit
==============
![icon~](https://raw.github.com/LaiFengiOS/LFLiveKit/master/LFLiveKitDemo/LFLiveKitDemo/Icon.png)
[![Build Status](https://travis-ci.org/LaiFengiOS/LFLiveKit.svg)](https://travis-ci.org/LaiFengiOS/LFLiveKit)&nbsp;
[![License MIT](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/chenliming777/LFLiveKit/master/LICENSE)&nbsp;
[![CocoaPods](http://img.shields.io/cocoapods/v/LFLiveKit.svg?style=flat)](http://cocoapods.org/?q=LFLiveKit)&nbsp;
[![Support](https://img.shields.io/badge/support-ios8%2B-orange.svg)](https://www.apple.com/nl/ios/)&nbsp;
[![Support](https://img.shields.io/badge/ios-7-orange.svg)](https://www.apple.com/nl/ios/)&nbsp;
![platform](https://img.shields.io/badge/platform-ios-ff69b4.svg)&nbsp;
## LFLiveKit
**LFLiveKit is a opensource RTMP streaming SDK for iOS.**
@@ -23,9 +26,15 @@
- [x] Switch camera position
- [x] Audio Mute
- [x] Support Send Buffer
- [x] Support WaterMark
- [x] Swift Support
- [x] Support Single Video or Audio
- [x] Support External input video or audio(Screen recording or Peripheral)
- [ ] ~~FLV package and send~~
## Requirements
- iOS 7.0+
- Xcode 7.3
## Installation
@@ -33,31 +42,45 @@
# To integrate LFLiveKit into your Xcode project using CocoaPods, specify it in your Podfile:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
platform :ios, '7.0'
pod 'LFLiveKit'
# Then, run the following command:
$ pod install
## Architecture:
#### Carthage
1. Add `github "LaiFengiOS/LFLiveKit"` to your Cartfile.
2. Run `carthage update --platform ios` and add the framework to your project.
3. Import \<LFLiveKit/LFLiveKit.h\>.
capture: LFAudioCapture and LFVideoCapture
encode: LFHardwareAudioEncoder and LFHardwareVideoEncoder
publish: LFStreamRtmpSocket
#### Manually
1. Download all the files in the `LFLiveKit` subdirectory.
2. Add the source files to your Xcode project.
3. Link with required frameworks:
* UIKit
* Foundation
* AVFoundation
* VideoToolbox
* AudioToolbox
* libz
* libstdc++
## Usage:
## Usage example
#### Objective-C
```
```objc
- (LFLiveSession*)session {
if (!_session) {
_session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:[LFLiveVideoConfiguration defaultConfiguration]];
_session.preView = self;
_session.delegate = self;
}
return _session;
if (!_session) {
_session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:[LFLiveVideoConfiguration defaultConfiguration]];
_session.preView = self;
_session.delegate = self;
}
return _session;
}
- (void)startLive {
LFLiveStreamInfo *streamInfo = [LFLiveStreamInfo new];
streamInfo.url = @"your server rtmp url";
@@ -72,34 +95,32 @@
- (void)liveSession:(nullable LFLiveSession *)session liveStateDidChange: (LFLiveState)state;
- (void)liveSession:(nullable LFLiveSession *)session debugInfo:(nullable LFLiveDebug*)debugInfo;
- (void)liveSession:(nullable LFLiveSession*)session errorCode:(LFLiveSocketErrorCode)errorCode;
```
#### Swift
```
```swift
// import LFLiveKit in [ProjectName]-Bridging-Header.h
import <LFLiveKit.h>
#import <LFLiveKit.h>
//MARK: - Getters and Setters
lazy var session: LFLiveSession = {
let audioConfiguration = LFLiveAudioConfiguration.defaultConfiguration()
let videoConfiguration = LFLiveVideoConfiguration.defaultConfigurationForQuality(LFLiveVideoQuality.Low3, landscape: false)
let session = LFLiveSession(audioConfiguration: audioConfiguration, videoConfiguration: videoConfiguration)
session?.delegate = self
session?.preView = self.view
return session!
let audioConfiguration = LFLiveAudioConfiguration.defaultConfiguration()
let videoConfiguration = LFLiveVideoConfiguration.defaultConfigurationForQuality(LFLiveVideoQuality.Low3, landscape: false)
let session = LFLiveSession(audioConfiguration: audioConfiguration, videoConfiguration: videoConfiguration)
session?.delegate = self
session?.preView = self.view
return session!
}()
//MARK: - Event
func startLive() -> Void {
let stream = LFLiveStreamInfo()
stream.url = "your server rtmp url";
session.startLive(stream)
let stream = LFLiveStreamInfo()
stream.url = "your server rtmp url";
session.startLive(stream)
}
func stopLive() -> Void {
session.stopLive()
session.stopLive()
}
//MARK: - Callback
@@ -108,6 +129,13 @@ func liveSession(session: LFLiveSession?, errorCode: LFLiveSocketErrorCode)
func liveSession(session: LFLiveSession?, liveStateDidChange state: LFLiveState)
```
## Release History
* 2.0.0
* CHANGE: modify bugs,support ios7 live.
* 2.2.4.3
* CHANGE: modify bugs,support swift import.
## License
**LFLiveKit is released under the MIT license. See LICENSE for details.**
@@ -7,184 +7,177 @@
objects = {
/* Begin PBXBuildFile section */
81E848D8BD2C446C2DD4876A /* libPods-LFLiveKitDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FD9F92833FE7856CDDD3CED /* libPods-LFLiveKitDemo.a */; };
B2D23E7F1D348F3D00B34CA8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B2D23E7E1D348F3D00B34CA8 /* main.m */; };
B2D23E821D348F3D00B34CA8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B2D23E811D348F3D00B34CA8 /* AppDelegate.m */; };
B2D23E851D348F3D00B34CA8 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B2D23E841D348F3D00B34CA8 /* ViewController.m */; };
B2D23E881D348F3D00B34CA8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B2D23E861D348F3D00B34CA8 /* Main.storyboard */; };
B2D23E8D1D348F3D00B34CA8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B2D23E8B1D348F3D00B34CA8 /* LaunchScreen.storyboard */; };
B2D23EAA1D348F7100B34CA8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B2D23E941D348F7100B34CA8 /* Assets.xcassets */; };
B2D23EAB1D348F7100B34CA8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B2D23E961D348F7100B34CA8 /* LaunchScreen.storyboard */; };
B2D23EAC1D348F7100B34CA8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B2D23E981D348F7100B34CA8 /* Main.storyboard */; };
B2D23EAD1D348F7100B34CA8 /* UIControl+YYAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = B2D23E9C1D348F7100B34CA8 /* UIControl+YYAdd.m */; };
B2D23EAE1D348F7100B34CA8 /* UIView+YYAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = B2D23E9E1D348F7100B34CA8 /* UIView+YYAdd.m */; };
B2D23EAF1D348F7100B34CA8 /* camra_beauty@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B2D23EA01D348F7100B34CA8 /* camra_beauty@2x.png */; };
B2D23EB01D348F7100B34CA8 /* camra_beauty@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B2D23EA11D348F7100B34CA8 /* camra_beauty@3x.png */; };
B2D23EB11D348F7100B34CA8 /* camra_beauty_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B2D23EA21D348F7100B34CA8 /* camra_beauty_close@2x.png */; };
B2D23EB21D348F7100B34CA8 /* camra_beauty_close@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B2D23EA31D348F7100B34CA8 /* camra_beauty_close@3x.png */; };
B2D23EB31D348F7100B34CA8 /* camra_preview@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B2D23EA41D348F7100B34CA8 /* camra_preview@2x.png */; };
B2D23EB41D348F7100B34CA8 /* camra_preview@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B2D23EA51D348F7100B34CA8 /* camra_preview@3x.png */; };
B2D23EB51D348F7100B34CA8 /* close_preview@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B2D23EA61D348F7100B34CA8 /* close_preview@2x.png */; };
B2D23EB61D348F7100B34CA8 /* close_preview@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B2D23EA71D348F7100B34CA8 /* close_preview@3x.png */; };
B2D23EB71D348F7100B34CA8 /* LFLivePreview.m in Sources */ = {isa = PBXBuildFile; fileRef = B2D23EA91D348F7100B34CA8 /* LFLivePreview.m */; };
84D8B42B1D75778B00752B56 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B42A1D75778B00752B56 /* main.m */; };
84D8B42E1D75778B00752B56 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B42D1D75778B00752B56 /* AppDelegate.m */; };
84D8B4311D75778B00752B56 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B4301D75778B00752B56 /* ViewController.m */; };
84D8B4341D75778B00752B56 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4321D75778B00752B56 /* Main.storyboard */; };
84D8B4361D75778B00752B56 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4351D75778B00752B56 /* Assets.xcassets */; };
84D8B4391D75778B00752B56 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4371D75778B00752B56 /* LaunchScreen.storyboard */; };
84D8B44B1D75781200752B56 /* LFLivePreview.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B44A1D75781200752B56 /* LFLivePreview.m */; };
84D8B45B1D75782700752B56 /* UIControl+YYAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B44E1D75782700752B56 /* UIControl+YYAdd.m */; };
84D8B45C1D75782700752B56 /* UIView+YYAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B4501D75782700752B56 /* UIView+YYAdd.m */; };
84D8B45D1D75782700752B56 /* camra_beauty@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4521D75782700752B56 /* camra_beauty@2x.png */; };
84D8B45E1D75782700752B56 /* camra_beauty@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4531D75782700752B56 /* camra_beauty@3x.png */; };
84D8B45F1D75782700752B56 /* camra_beauty_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4541D75782700752B56 /* camra_beauty_close@2x.png */; };
84D8B4601D75782700752B56 /* camra_beauty_close@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4551D75782700752B56 /* camra_beauty_close@3x.png */; };
84D8B4611D75782700752B56 /* camra_preview@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4561D75782700752B56 /* camra_preview@2x.png */; };
84D8B4621D75782700752B56 /* camra_preview@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4571D75782700752B56 /* camra_preview@3x.png */; };
84D8B4631D75782700752B56 /* close_preview@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4581D75782700752B56 /* close_preview@2x.png */; };
84D8B4641D75782700752B56 /* close_preview@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4591D75782700752B56 /* close_preview@3x.png */; };
84D8B4651D75782700752B56 /* ios-29x29.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B45A1D75782700752B56 /* ios-29x29.png */; };
84D8B4CF1D757F0700752B56 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4CE1D757F0700752B56 /* libstdc++.tbd */; };
BC8B37EEE1CEEF9B5614DC91 /* libPods-LFLiveKitDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B1CCEEE06FCFAF75D105A51 /* libPods-LFLiveKitDemo.a */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
6FD9F92833FE7856CDDD3CED /* libPods-LFLiveKitDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LFLiveKitDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; };
8FAAEBE1A4F099C69588B394 /* Pods-LFLiveKitDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LFLiveKitDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-LFLiveKitDemo/Pods-LFLiveKitDemo.release.xcconfig"; sourceTree = "<group>"; };
AFD491825C5DB2AD871189B5 /* Pods-LFLiveKitDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LFLiveKitDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LFLiveKitDemo/Pods-LFLiveKitDemo.debug.xcconfig"; sourceTree = "<group>"; };
B2D23E7A1D348F3D00B34CA8 /* LFLiveKitDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LFLiveKitDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
B2D23E7E1D348F3D00B34CA8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
B2D23E801D348F3D00B34CA8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
B2D23E811D348F3D00B34CA8 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
B2D23E831D348F3D00B34CA8 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
B2D23E841D348F3D00B34CA8 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
B2D23E871D348F3D00B34CA8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
B2D23E8C1D348F3D00B34CA8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
B2D23E8E1D348F3D00B34CA8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B2D23E941D348F7100B34CA8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
B2D23E971D348F7100B34CA8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
B2D23E991D348F7100B34CA8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Main.storyboard; sourceTree = "<group>"; };
B2D23E9B1D348F7100B34CA8 /* UIControl+YYAdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIControl+YYAdd.h"; sourceTree = "<group>"; };
B2D23E9C1D348F7100B34CA8 /* UIControl+YYAdd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIControl+YYAdd.m"; sourceTree = "<group>"; };
B2D23E9D1D348F7100B34CA8 /* UIView+YYAdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+YYAdd.h"; sourceTree = "<group>"; };
B2D23E9E1D348F7100B34CA8 /* UIView+YYAdd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+YYAdd.m"; sourceTree = "<group>"; };
B2D23EA01D348F7100B34CA8 /* camra_beauty@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty@2x.png"; sourceTree = "<group>"; };
B2D23EA11D348F7100B34CA8 /* camra_beauty@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty@3x.png"; sourceTree = "<group>"; };
B2D23EA21D348F7100B34CA8 /* camra_beauty_close@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty_close@2x.png"; sourceTree = "<group>"; };
B2D23EA31D348F7100B34CA8 /* camra_beauty_close@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty_close@3x.png"; sourceTree = "<group>"; };
B2D23EA41D348F7100B34CA8 /* camra_preview@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_preview@2x.png"; sourceTree = "<group>"; };
B2D23EA51D348F7100B34CA8 /* camra_preview@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_preview@3x.png"; sourceTree = "<group>"; };
B2D23EA61D348F7100B34CA8 /* close_preview@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "close_preview@2x.png"; sourceTree = "<group>"; };
B2D23EA71D348F7100B34CA8 /* close_preview@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "close_preview@3x.png"; sourceTree = "<group>"; };
B2D23EA81D348F7100B34CA8 /* LFLivePreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLivePreview.h; sourceTree = "<group>"; };
B2D23EA91D348F7100B34CA8 /* LFLivePreview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLivePreview.m; sourceTree = "<group>"; };
289A9C4510CD7EA6F4CE9897 /* Pods-LFLiveKitDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LFLiveKitDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LFLiveKitDemo/Pods-LFLiveKitDemo.debug.xcconfig"; sourceTree = "<group>"; };
5B1CCEEE06FCFAF75D105A51 /* libPods-LFLiveKitDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LFLiveKitDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; };
84D8B4261D75778B00752B56 /* LFLiveKitDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LFLiveKitDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
84D8B42A1D75778B00752B56 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
84D8B42C1D75778B00752B56 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
84D8B42D1D75778B00752B56 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
84D8B42F1D75778B00752B56 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
84D8B4301D75778B00752B56 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
84D8B4331D75778B00752B56 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
84D8B4351D75778B00752B56 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
84D8B4381D75778B00752B56 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
84D8B43A1D75778B00752B56 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
84D8B4491D75781200752B56 /* LFLivePreview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLivePreview.h; sourceTree = "<group>"; };
84D8B44A1D75781200752B56 /* LFLivePreview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLivePreview.m; sourceTree = "<group>"; };
84D8B44D1D75782700752B56 /* UIControl+YYAdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIControl+YYAdd.h"; sourceTree = "<group>"; };
84D8B44E1D75782700752B56 /* UIControl+YYAdd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIControl+YYAdd.m"; sourceTree = "<group>"; };
84D8B44F1D75782700752B56 /* UIView+YYAdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+YYAdd.h"; sourceTree = "<group>"; };
84D8B4501D75782700752B56 /* UIView+YYAdd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+YYAdd.m"; sourceTree = "<group>"; };
84D8B4521D75782700752B56 /* camra_beauty@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty@2x.png"; sourceTree = "<group>"; };
84D8B4531D75782700752B56 /* camra_beauty@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty@3x.png"; sourceTree = "<group>"; };
84D8B4541D75782700752B56 /* camra_beauty_close@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty_close@2x.png"; sourceTree = "<group>"; };
84D8B4551D75782700752B56 /* camra_beauty_close@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_beauty_close@3x.png"; sourceTree = "<group>"; };
84D8B4561D75782700752B56 /* camra_preview@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_preview@2x.png"; sourceTree = "<group>"; };
84D8B4571D75782700752B56 /* camra_preview@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_preview@3x.png"; sourceTree = "<group>"; };
84D8B4581D75782700752B56 /* close_preview@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "close_preview@2x.png"; sourceTree = "<group>"; };
84D8B4591D75782700752B56 /* close_preview@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "close_preview@3x.png"; sourceTree = "<group>"; };
84D8B45A1D75782700752B56 /* ios-29x29.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ios-29x29.png"; sourceTree = "<group>"; };
84D8B4CE1D757F0700752B56 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; };
96E1231310083A3881AD2AB6 /* Pods-LFLiveKitDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LFLiveKitDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-LFLiveKitDemo/Pods-LFLiveKitDemo.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
B2D23E771D348F3D00B34CA8 /* Frameworks */ = {
84D8B4231D75778B00752B56 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
81E848D8BD2C446C2DD4876A /* libPods-LFLiveKitDemo.a in Frameworks */,
84D8B4CF1D757F0700752B56 /* libstdc++.tbd in Frameworks */,
BC8B37EEE1CEEF9B5614DC91 /* libPods-LFLiveKitDemo.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
2A74A5AD65CD9450ED23C3E0 /* Pods */ = {
65E0CF98FF954863E543A0E1 /* Frameworks */ = {
isa = PBXGroup;
children = (
AFD491825C5DB2AD871189B5 /* Pods-LFLiveKitDemo.debug.xcconfig */,
8FAAEBE1A4F099C69588B394 /* Pods-LFLiveKitDemo.release.xcconfig */,
5B1CCEEE06FCFAF75D105A51 /* libPods-LFLiveKitDemo.a */,
);
name = Pods;
name = Frameworks;
sourceTree = "<group>";
};
B2D23E711D348F3D00B34CA8 = {
84D8B41D1D75778B00752B56 = {
isa = PBXGroup;
children = (
B2D23E7C1D348F3D00B34CA8 /* LFLiveKitDemo */,
B2D23E7B1D348F3D00B34CA8 /* Products */,
2A74A5AD65CD9450ED23C3E0 /* Pods */,
E6AF2D0BFA2946745BB5F365 /* Frameworks */,
84D8B4CE1D757F0700752B56 /* libstdc++.tbd */,
84D8B4281D75778B00752B56 /* LFLiveKitDemo */,
84D8B4271D75778B00752B56 /* Products */,
F3E359B8A7561F963C47A62F /* Pods */,
65E0CF98FF954863E543A0E1 /* Frameworks */,
);
sourceTree = "<group>";
};
B2D23E7B1D348F3D00B34CA8 /* Products */ = {
84D8B4271D75778B00752B56 /* Products */ = {
isa = PBXGroup;
children = (
B2D23E7A1D348F3D00B34CA8 /* LFLiveKitDemo.app */,
84D8B4261D75778B00752B56 /* LFLiveKitDemo.app */,
);
name = Products;
sourceTree = "<group>";
};
B2D23E7C1D348F3D00B34CA8 /* LFLiveKitDemo */ = {
84D8B4281D75778B00752B56 /* LFLiveKitDemo */ = {
isa = PBXGroup;
children = (
B2D23E941D348F7100B34CA8 /* Assets.xcassets */,
B2D23E951D348F7100B34CA8 /* Base.lproj */,
B2D23E9A1D348F7100B34CA8 /* category */,
B2D23E9F1D348F7100B34CA8 /* images */,
B2D23EA81D348F7100B34CA8 /* LFLivePreview.h */,
B2D23EA91D348F7100B34CA8 /* LFLivePreview.m */,
B2D23E801D348F3D00B34CA8 /* AppDelegate.h */,
B2D23E811D348F3D00B34CA8 /* AppDelegate.m */,
B2D23E831D348F3D00B34CA8 /* ViewController.h */,
B2D23E841D348F3D00B34CA8 /* ViewController.m */,
B2D23E861D348F3D00B34CA8 /* Main.storyboard */,
B2D23E8B1D348F3D00B34CA8 /* LaunchScreen.storyboard */,
B2D23E8E1D348F3D00B34CA8 /* Info.plist */,
B2D23E7D1D348F3D00B34CA8 /* Supporting Files */,
84D8B42C1D75778B00752B56 /* AppDelegate.h */,
84D8B42D1D75778B00752B56 /* AppDelegate.m */,
84D8B42F1D75778B00752B56 /* ViewController.h */,
84D8B4301D75778B00752B56 /* ViewController.m */,
84D8B4491D75781200752B56 /* LFLivePreview.h */,
84D8B44A1D75781200752B56 /* LFLivePreview.m */,
84D8B44C1D75782700752B56 /* category */,
84D8B4511D75782700752B56 /* images */,
84D8B4321D75778B00752B56 /* Main.storyboard */,
84D8B4351D75778B00752B56 /* Assets.xcassets */,
84D8B4371D75778B00752B56 /* LaunchScreen.storyboard */,
84D8B43A1D75778B00752B56 /* Info.plist */,
84D8B4291D75778B00752B56 /* Supporting Files */,
);
path = LFLiveKitDemo;
sourceTree = "<group>";
};
B2D23E7D1D348F3D00B34CA8 /* Supporting Files */ = {
84D8B4291D75778B00752B56 /* Supporting Files */ = {
isa = PBXGroup;
children = (
B2D23E7E1D348F3D00B34CA8 /* main.m */,
84D8B42A1D75778B00752B56 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
B2D23E951D348F7100B34CA8 /* Base.lproj */ = {
84D8B44C1D75782700752B56 /* category */ = {
isa = PBXGroup;
children = (
B2D23E961D348F7100B34CA8 /* LaunchScreen.storyboard */,
B2D23E981D348F7100B34CA8 /* Main.storyboard */,
);
path = Base.lproj;
sourceTree = "<group>";
};
B2D23E9A1D348F7100B34CA8 /* category */ = {
isa = PBXGroup;
children = (
B2D23E9B1D348F7100B34CA8 /* UIControl+YYAdd.h */,
B2D23E9C1D348F7100B34CA8 /* UIControl+YYAdd.m */,
B2D23E9D1D348F7100B34CA8 /* UIView+YYAdd.h */,
B2D23E9E1D348F7100B34CA8 /* UIView+YYAdd.m */,
84D8B44D1D75782700752B56 /* UIControl+YYAdd.h */,
84D8B44E1D75782700752B56 /* UIControl+YYAdd.m */,
84D8B44F1D75782700752B56 /* UIView+YYAdd.h */,
84D8B4501D75782700752B56 /* UIView+YYAdd.m */,
);
path = category;
sourceTree = "<group>";
};
B2D23E9F1D348F7100B34CA8 /* images */ = {
84D8B4511D75782700752B56 /* images */ = {
isa = PBXGroup;
children = (
B2D23EA01D348F7100B34CA8 /* camra_beauty@2x.png */,
B2D23EA11D348F7100B34CA8 /* camra_beauty@3x.png */,
B2D23EA21D348F7100B34CA8 /* camra_beauty_close@2x.png */,
B2D23EA31D348F7100B34CA8 /* camra_beauty_close@3x.png */,
B2D23EA41D348F7100B34CA8 /* camra_preview@2x.png */,
B2D23EA51D348F7100B34CA8 /* camra_preview@3x.png */,
B2D23EA61D348F7100B34CA8 /* close_preview@2x.png */,
B2D23EA71D348F7100B34CA8 /* close_preview@3x.png */,
84D8B4521D75782700752B56 /* camra_beauty@2x.png */,
84D8B4531D75782700752B56 /* camra_beauty@3x.png */,
84D8B4541D75782700752B56 /* camra_beauty_close@2x.png */,
84D8B4551D75782700752B56 /* camra_beauty_close@3x.png */,
84D8B4561D75782700752B56 /* camra_preview@2x.png */,
84D8B4571D75782700752B56 /* camra_preview@3x.png */,
84D8B4581D75782700752B56 /* close_preview@2x.png */,
84D8B4591D75782700752B56 /* close_preview@3x.png */,
84D8B45A1D75782700752B56 /* ios-29x29.png */,
);
path = images;
sourceTree = "<group>";
};
E6AF2D0BFA2946745BB5F365 /* Frameworks */ = {
F3E359B8A7561F963C47A62F /* Pods */ = {
isa = PBXGroup;
children = (
6FD9F92833FE7856CDDD3CED /* libPods-LFLiveKitDemo.a */,
289A9C4510CD7EA6F4CE9897 /* Pods-LFLiveKitDemo.debug.xcconfig */,
96E1231310083A3881AD2AB6 /* Pods-LFLiveKitDemo.release.xcconfig */,
);
name = Frameworks;
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
B2D23E791D348F3D00B34CA8 /* LFLiveKitDemo */ = {
84D8B4251D75778B00752B56 /* LFLiveKitDemo */ = {
isa = PBXNativeTarget;
buildConfigurationList = B2D23E911D348F3D00B34CA8 /* Build configuration list for PBXNativeTarget "LFLiveKitDemo" */;
buildConfigurationList = 84D8B43D1D75778B00752B56 /* Build configuration list for PBXNativeTarget "LFLiveKitDemo" */;
buildPhases = (
64B4341F5B9578C3E50D0608 /* 📦 Check Pods Manifest.lock */,
B2D23E761D348F3D00B34CA8 /* Sources */,
B2D23E771D348F3D00B34CA8 /* Frameworks */,
B2D23E781D348F3D00B34CA8 /* Resources */,
90A9D0B9FC19DB224CE96A04 /* 📦 Embed Pods Frameworks */,
5CD44155361B18A2D8700198 /* 📦 Copy Pods Resources */,
A819C09CC049A57DC5C97E12 /* 📦 Check Pods Manifest.lock */,
84D8B4221D75778B00752B56 /* Sources */,
84D8B4231D75778B00752B56 /* Frameworks */,
84D8B4241D75778B00752B56 /* Resources */,
883533331BE4DCC0DB5075CF /* 📦 Embed Pods Frameworks */,
4CC4C37B93D109913E475307 /* 📦 Copy Pods Resources */,
);
buildRules = (
);
@@ -192,24 +185,25 @@
);
name = LFLiveKitDemo;
productName = LFLiveKitDemo;
productReference = B2D23E7A1D348F3D00B34CA8 /* LFLiveKitDemo.app */;
productReference = 84D8B4261D75778B00752B56 /* LFLiveKitDemo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
B2D23E721D348F3D00B34CA8 /* Project object */ = {
84D8B41E1D75778B00752B56 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = zhanqi.tv;
ORGANIZATIONNAME = admin;
TargetAttributes = {
B2D23E791D348F3D00B34CA8 = {
CreatedOnToolsVersion = 7.3;
84D8B4251D75778B00752B56 = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = G497YX6CBT;
};
};
};
buildConfigurationList = B2D23E751D348F3D00B34CA8 /* Build configuration list for PBXProject "LFLiveKitDemo" */;
buildConfigurationList = 84D8B4211D75778B00752B56 /* Build configuration list for PBXProject "LFLiveKitDemo" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
@@ -217,41 +211,40 @@
en,
Base,
);
mainGroup = B2D23E711D348F3D00B34CA8;
productRefGroup = B2D23E7B1D348F3D00B34CA8 /* Products */;
mainGroup = 84D8B41D1D75778B00752B56;
productRefGroup = 84D8B4271D75778B00752B56 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
B2D23E791D348F3D00B34CA8 /* LFLiveKitDemo */,
84D8B4251D75778B00752B56 /* LFLiveKitDemo */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
B2D23E781D348F3D00B34CA8 /* Resources */ = {
84D8B4241D75778B00752B56 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B2D23E8D1D348F3D00B34CA8 /* LaunchScreen.storyboard in Resources */,
B2D23EAA1D348F7100B34CA8 /* Assets.xcassets in Resources */,
B2D23EAC1D348F7100B34CA8 /* Main.storyboard in Resources */,
B2D23EAB1D348F7100B34CA8 /* LaunchScreen.storyboard in Resources */,
B2D23EB21D348F7100B34CA8 /* camra_beauty_close@3x.png in Resources */,
B2D23EAF1D348F7100B34CA8 /* camra_beauty@2x.png in Resources */,
B2D23EB61D348F7100B34CA8 /* close_preview@3x.png in Resources */,
B2D23EB41D348F7100B34CA8 /* camra_preview@3x.png in Resources */,
B2D23EB51D348F7100B34CA8 /* close_preview@2x.png in Resources */,
B2D23EB11D348F7100B34CA8 /* camra_beauty_close@2x.png in Resources */,
B2D23EB01D348F7100B34CA8 /* camra_beauty@3x.png in Resources */,
B2D23EB31D348F7100B34CA8 /* camra_preview@2x.png in Resources */,
B2D23E881D348F3D00B34CA8 /* Main.storyboard in Resources */,
84D8B45F1D75782700752B56 /* camra_beauty_close@2x.png in Resources */,
84D8B4391D75778B00752B56 /* LaunchScreen.storyboard in Resources */,
84D8B45D1D75782700752B56 /* camra_beauty@2x.png in Resources */,
84D8B4361D75778B00752B56 /* Assets.xcassets in Resources */,
84D8B4621D75782700752B56 /* camra_preview@3x.png in Resources */,
84D8B4601D75782700752B56 /* camra_beauty_close@3x.png in Resources */,
84D8B4651D75782700752B56 /* ios-29x29.png in Resources */,
84D8B4641D75782700752B56 /* close_preview@3x.png in Resources */,
84D8B4631D75782700752B56 /* close_preview@2x.png in Resources */,
84D8B4341D75778B00752B56 /* Main.storyboard in Resources */,
84D8B4611D75782700752B56 /* camra_preview@2x.png in Resources */,
84D8B45E1D75782700752B56 /* camra_beauty@3x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
5CD44155361B18A2D8700198 /* 📦 Copy Pods Resources */ = {
4CC4C37B93D109913E475307 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -266,22 +259,7 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LFLiveKitDemo/Pods-LFLiveKitDemo-resources.sh\"\n";
showEnvVarsInLog = 0;
};
64B4341F5B9578C3E50D0608 /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
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";
showEnvVarsInLog = 0;
};
90A9D0B9FC19DB224CE96A04 /* 📦 Embed Pods Frameworks */ = {
883533331BE4DCC0DB5075CF /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -296,61 +274,60 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LFLiveKitDemo/Pods-LFLiveKitDemo-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
A819C09CC049A57DC5C97E12 /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
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";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
B2D23E761D348F3D00B34CA8 /* Sources */ = {
84D8B4221D75778B00752B56 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B2D23EB71D348F7100B34CA8 /* LFLivePreview.m in Sources */,
B2D23E851D348F3D00B34CA8 /* ViewController.m in Sources */,
B2D23EAD1D348F7100B34CA8 /* UIControl+YYAdd.m in Sources */,
B2D23E821D348F3D00B34CA8 /* AppDelegate.m in Sources */,
B2D23EAE1D348F7100B34CA8 /* UIView+YYAdd.m in Sources */,
B2D23E7F1D348F3D00B34CA8 /* main.m in Sources */,
84D8B45B1D75782700752B56 /* UIControl+YYAdd.m in Sources */,
84D8B4311D75778B00752B56 /* ViewController.m in Sources */,
84D8B45C1D75782700752B56 /* UIView+YYAdd.m in Sources */,
84D8B42E1D75778B00752B56 /* AppDelegate.m in Sources */,
84D8B44B1D75781200752B56 /* LFLivePreview.m in Sources */,
84D8B42B1D75778B00752B56 /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
B2D23E861D348F3D00B34CA8 /* Main.storyboard */ = {
84D8B4321D75778B00752B56 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
B2D23E871D348F3D00B34CA8 /* Base */,
84D8B4331D75778B00752B56 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
B2D23E8B1D348F3D00B34CA8 /* LaunchScreen.storyboard */ = {
84D8B4371D75778B00752B56 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
B2D23E8C1D348F3D00B34CA8 /* Base */,
84D8B4381D75778B00752B56 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
B2D23E961D348F7100B34CA8 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
B2D23E971D348F7100B34CA8 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
B2D23E981D348F7100B34CA8 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
B2D23E991D348F7100B34CA8 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
B2D23E8F1D348F3D00B34CA8 /* Debug */ = {
84D8B43B1D75778B00752B56 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
@@ -373,7 +350,6 @@
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -388,17 +364,14 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "$(inherited)";
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
LIBRARY_SEARCH_PATHS = "$(inherited)";
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "$(inherited)";
SDKROOT = iphoneos;
};
name = Debug;
};
B2D23E901D348F3D00B34CA8 /* Release */ = {
84D8B43C1D75778B00752B56 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
@@ -421,7 +394,6 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -430,46 +402,45 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "$(inherited)";
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
LIBRARY_SEARCH_PATHS = "$(inherited)";
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_LDFLAGS = "$(inherited)";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
B2D23E921D348F3D00B34CA8 /* Debug */ = {
84D8B43E1D75778B00752B56 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AFD491825C5DB2AD871189B5 /* Pods-LFLiveKitDemo.debug.xcconfig */;
baseConfigurationReference = 289A9C4510CD7EA6F4CE9897 /* Pods-LFLiveKitDemo.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = G497YX6CBT;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = LFLiveKitDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.gameabc.LFLiveKitDemo;
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LaiFeng;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
B2D23E931D348F3D00B34CA8 /* Release */ = {
84D8B43F1D75778B00752B56 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 8FAAEBE1A4F099C69588B394 /* Pods-LFLiveKitDemo.release.xcconfig */;
baseConfigurationReference = 96E1231310083A3881AD2AB6 /* Pods-LFLiveKitDemo.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = G497YX6CBT;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = LFLiveKitDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.gameabc.LFLiveKitDemo;
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LaiFeng;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@@ -477,25 +448,25 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
B2D23E751D348F3D00B34CA8 /* Build configuration list for PBXProject "LFLiveKitDemo" */ = {
84D8B4211D75778B00752B56 /* Build configuration list for PBXProject "LFLiveKitDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B2D23E8F1D348F3D00B34CA8 /* Debug */,
B2D23E901D348F3D00B34CA8 /* Release */,
84D8B43B1D75778B00752B56 /* Debug */,
84D8B43C1D75778B00752B56 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B2D23E911D348F3D00B34CA8 /* Build configuration list for PBXNativeTarget "LFLiveKitDemo" */ = {
84D8B43D1D75778B00752B56 /* Build configuration list for PBXNativeTarget "LFLiveKitDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B2D23E921D348F3D00B34CA8 /* Debug */,
B2D23E931D348F3D00B34CA8 /* Release */,
84D8B43E1D75778B00752B56 /* Debug */,
84D8B43F1D75778B00752B56 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = B2D23E721D348F3D00B34CA8 /* Project object */;
rootObject = 84D8B41E1D75778B00752B56 /* Project object */;
}
@@ -2,7 +2,7 @@
// AppDelegate.h
// LFLiveKitDemo
//
// Created by admin on 16/6/8.
// Created by admin on 16/8/30.
// Copyright © 2016年 admin. All rights reserved.
//
@@ -2,12 +2,11 @@
// AppDelegate.m
// LFLiveKitDemo
//
// Created by admin on 16/6/8.
// Created by admin on 16/8/30.
// Copyright © 2016 admin. All rights reserved.
//
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@@ -18,17 +17,9 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
// nav.navigationBarHidden = YES;
self.window.rootViewController = [[ViewController alloc] init];
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@@ -22,26 +22,20 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>NSCameraUsageDescription</key>
<string>cameraDesciption</string>
<key>NSMicrophoneUsageDescription</key>
<string>microphoneDesciption</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
@@ -9,7 +9,7 @@
#import "LFLivePreview.h"
#import "UIControl+YYAdd.h"
#import "UIView+YYAdd.h"
#import "LFLiveSession.h"
#import "LFLiveKit.h"
inline static NSString *formatedSpeed(float bytes, float elapsed_milli) {
if (elapsed_milli <= 0) {
@@ -156,7 +156,17 @@ inline static NSString *formatedSpeed(float bytes, float elapsed_milli) {
/***  默认分辨率368 640 音频:44.1 iphone6以上48 双声道 方向竖屏 ***/
_session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:[LFLiveVideoConfiguration defaultConfigurationForQuality:LFLiveVideoQuality_Medium2 landscape:NO]];
LFLiveVideoConfiguration *videoConfiguration = [LFLiveVideoConfiguration new];
videoConfiguration.videoSize = CGSizeMake(640, 360);
videoConfiguration.videoBitRate = 800*1024;
videoConfiguration.videoMaxBitRate = 1000*1024;
videoConfiguration.videoMinBitRate = 500*1024;
videoConfiguration.videoFrameRate = 24;
videoConfiguration.videoMaxKeyframeInterval = 48;
videoConfiguration.outputImageOrientation = UIInterfaceOrientationLandscapeLeft;
videoConfiguration.autorotate = NO;
videoConfiguration.sessionPreset = LFCaptureSessionPreset720x1280;
_session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:videoConfiguration captureType:LFLiveCaptureDefaultMask];
/**   自己定制单声道 */
/*
@@ -213,8 +223,8 @@ inline static NSString *formatedSpeed(float bytes, float elapsed_milli) {
videoConfiguration.videoMinBitRate = 500*1024;
videoConfiguration.videoFrameRate = 15;
videoConfiguration.videoMaxKeyframeInterval = 30;
videoConfiguration.orientation = UIInterfaceOrientationPortrait;
videoConfiguration.sessionPreset = LFCaptureSessionPreset720x1280;
videoConfiguration.landscape = NO;
videoConfiguration.sessionPreset = LFCaptureSessionPreset360x640;
_session = [[LFLiveSession alloc] initWithAudioConfiguration:audioConfiguration videoConfiguration:videoConfiguration];
*/
@@ -239,11 +249,26 @@ inline static NSString *formatedSpeed(float bytes, float elapsed_milli) {
videoConfiguration.sessionPreset = LFCaptureSessionPreset720x1280;
_session = [[LFLiveSession alloc] initWithAudioConfiguration:audioConfiguration videoConfiguration:videoConfiguration];
*/
*/
_session.delegate = self;
_session.showDebugInfo = NO;
_session.preView = self;
/*本地存储*/
// _session.saveLocalVideo = YES;
// NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.mp4"];
// unlink([pathToMovie UTF8String]); // If a file already exists, AVAssetWriter won't let you record new frames, so delete the old movie
// NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
// _session.saveLocalVideoPath = movieURL;
/*
UIImageView *imageView = [[UIImageView alloc] init];
imageView.alpha = 0.8;
imageView.frame = CGRectMake(100, 100, 29, 29);
imageView.image = [UIImage imageNamed:@"ios-29x29"];
_session.warterMarkView = imageView;*/
}
return _session;
}
@@ -304,8 +329,8 @@ inline static NSString *formatedSpeed(float bytes, float elapsed_milli) {
_beautyButton = [UIButton new];
_beautyButton.size = CGSizeMake(44, 44);
_beautyButton.origin = CGPointMake(_cameraButton.left - 10 - _beautyButton.width, 20);
[_beautyButton setImage:[UIImage imageNamed:@"camra_beauty"] forState:UIControlStateSelected];
[_beautyButton setImage:[UIImage imageNamed:@"camra_beauty_close"] forState:UIControlStateNormal];
[_beautyButton setImage:[UIImage imageNamed:@"camra_beauty"] forState:UIControlStateNormal];
[_beautyButton setImage:[UIImage imageNamed:@"camra_beauty_close"] forState:UIControlStateSelected];
_beautyButton.exclusiveTouch = YES;
__weak typeof(self) _self = self;
[_beautyButton addBlockForControlEvents:UIControlEventTouchUpInside block:^(id sender) {
@@ -334,7 +359,7 @@ inline static NSString *formatedSpeed(float bytes, float elapsed_milli) {
if (_self.startLiveButton.selected) {
[_self.startLiveButton setTitle:@"结束直播" forState:UIControlStateNormal];
LFLiveStreamInfo *stream = [LFLiveStreamInfo new];
stream.url = @"rtmp://live.hkstv.hk.lxdns.com:1935/live/stream123";
stream.url = @"rtmp://live.hkstv.hk.lxdns.com:1935/live/stream153";
[_self.session startLive:stream];
} else {
[_self.startLiveButton setTitle:@"开始直播" forState:UIControlStateNormal];
@@ -2,7 +2,7 @@
// ViewController.h
// LFLiveKitDemo
//
// Created by admin on 16/6/8.
// Created by admin on 16/8/30.
// Copyright © 2016年 admin. All rights reserved.
//

Some files were not shown because too many files have changed in this diff Show More