Compare commits

...

28 Commits

Author SHA1 Message Date
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
251 changed files with 745 additions and 9641 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
language: objective-c
osx_image: xcode7
xcode_project: LFLiveKit/LFLiveKit.xcodeproj
xcode_project: FrameWork/LFLiveKit.xcodeproj
xcode_scheme: LFLiveKit
script:
- xctool -project LFLiveKit/LFLiveKit.xcodeproj -scheme 'LFLiveKit' -configuration Release -sdk iphonesimulator -arch i386 build
- xctool -project FrameWork/LFLiveKit.xcodeproj -scheme 'LFLiveKit' -configuration Release -sdk iphonesimulator -arch i386 build
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.2.4.3</string>
<string>2.4.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+80 -23
View File
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
1F3858C76FA5230BD4B34FEF /* libPods-LFLiveKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D9E53AEC8F2938295308B625 /* libPods-LFLiveKit.a */; };
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 */; };
@@ -32,26 +33,26 @@
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 */; };
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 */; };
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 */; };
84D8B5D81D768B6E00752B56 /* LFLiveSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A61D768B6E00752B56 /* LFLiveSession.h */; };
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 */; };
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 */; };
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 */; };
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 */; };
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 */; };
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 */; };
@@ -63,6 +64,7 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
7F7E051931BABE0B14FE6A57 /* 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>"; };
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; };
@@ -119,6 +121,8 @@
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>"; };
BF1D108D206BBD2267CDB4FB /* 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>"; };
D9E53AEC8F2938295308B625 /* libPods-LFLiveKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LFLiveKit.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -131,6 +135,7 @@
84D8B4C31D757EC400752B56 /* AVFoundation.framework in Frameworks */,
84D8B4C11D757EBE00752B56 /* AudioToolbox.framework in Frameworks */,
84D8B4BF1D757EB800752B56 /* VideoToolbox.framework in Frameworks */,
1F3858C76FA5230BD4B34FEF /* libPods-LFLiveKit.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -149,6 +154,8 @@
84D8B4C01D757EBE00752B56 /* AudioToolbox.framework */,
84D8B4BE1D757EB800752B56 /* VideoToolbox.framework */,
84D8B3911D7574D600752B56 /* Products */,
D77470616157694EC6FD0A0D /* Pods */,
9ABACAFFC334034AA0115426 /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -272,6 +279,23 @@
path = publish;
sourceTree = "<group>";
};
9ABACAFFC334034AA0115426 /* Frameworks */ = {
isa = PBXGroup;
children = (
D9E53AEC8F2938295308B625 /* libPods-LFLiveKit.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
D77470616157694EC6FD0A0D /* Pods */ = {
isa = PBXGroup;
children = (
7F7E051931BABE0B14FE6A57 /* Pods-LFLiveKit.debug.xcconfig */,
BF1D108D206BBD2267CDB4FB /* Pods-LFLiveKit.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -282,27 +306,27 @@
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 */,
84D8B5E01D768B6E00752B56 /* LFLiveStreamInfo.h in Headers */,
84D8B5C51D768B6E00752B56 /* LFVideoEncoder.h in Headers */,
84D8B5D11D768B6E00752B56 /* LFLiveVideoConfiguration.h in Headers */,
84D8B5D51D768B6E00752B56 /* LFGPUImageEmptyFilter.h in Headers */,
84D8B5C71D768B6E00752B56 /* LFAudioEncoding.h in Headers */,
84D8B5DC1D768B6E00752B56 /* LFFrame.h in Headers */,
84D8B5E91D768B6E00752B56 /* NSMutableArray+LFAdd.h in Headers */,
84D8B5CC1D768B6E00752B56 /* LFHardwareVideoEncoder.h in Headers */,
84D8B5BD1D768B6E00752B56 /* LFVideoCapture.h in Headers */,
84D8B5D71D768B6E00752B56 /* LFLiveKit.h in Headers */,
84D8B5E81D768B6E00752B56 /* LFStreamSocket.h in Headers */,
84D8B5D81D768B6E00752B56 /* LFLiveSession.h in Headers */,
84D8B5C41D768B6E00752B56 /* LFNALUnit.h in Headers */,
84D8B5CA1D768B6E00752B56 /* LFHardwareAudioEncoder.h in Headers */,
84D8B5CE1D768B6E00752B56 /* LFVideoEncoding.h in Headers */,
84D8B5E21D768B6E00752B56 /* LFVideoFrame.h in Headers */,
84D8B5E41D768B6E00752B56 /* LFStreamingBuffer.h in Headers */,
84D8B5C81D768B6E00752B56 /* LFH264VideoEncoder.h in Headers */,
);
@@ -315,10 +339,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 84D8B3981D7574D600752B56 /* Build configuration list for PBXNativeTarget "LFLiveKit" */;
buildPhases = (
2833F857062C89FFF3975A1B /* 📦 Check Pods Manifest.lock */,
84D8B38B1D7574D600752B56 /* Sources */,
84D8B38C1D7574D600752B56 /* Frameworks */,
84D8B38D1D7574D600752B56 /* Headers */,
84D8B38E1D7574D600752B56 /* Resources */,
D64BB080ABC44A32A8D6E2CF /* 📦 Copy Pods Resources */,
);
buildRules = (
);
@@ -370,6 +396,39 @@
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
2833F857062C89FFF3975A1B /* 📦 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;
};
D64BB080ABC44A32A8D6E2CF /* 📦 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;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
84D8B38B1D7574D600752B56 /* Sources */ = {
isa = PBXSourcesBuildPhase;
@@ -495,19 +554,18 @@
};
84D8B3991D7574D600752B56 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7F7E051931BABE0B14FE6A57 /* Pods-LFLiveKit.debug.xcconfig */;
buildSettings = {
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../Vendor/GPUImage.framework/Headers\"",
"\"$(SRCROOT)/../Vendor/pili-librtmp.framework/Headers\"",
);
HEADER_SEARCH_PATHS = "$(inherited)";
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;
@@ -518,19 +576,18 @@
};
84D8B39A1D7574D600752B56 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = BF1D108D206BBD2267CDB4FB /* Pods-LFLiveKit.release.xcconfig */;
buildSettings = {
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../Vendor/GPUImage.framework/Headers\"",
"\"$(SRCROOT)/../Vendor/pili-librtmp.framework/Headers\"",
);
HEADER_SEARCH_PATHS = "$(inherited)";
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;
+7
View File
@@ -0,0 +1,7 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios,'7.0'
target “LFLiveKit” do
pod 'pili-librtmp', '~> 1.0.3.1'
pod 'LMGPUImage'
end
+3 -4
View File
@@ -2,7 +2,7 @@
Pod::Spec.new do |s|
s.name = "LFLiveKit"
s.version = "2.2.4.3"
s.version = "2.4.2"
s.summary = "LaiFeng ios Live. LFLiveKit."
s.homepage = "https://github.com/chenliming777"
s.license = { :type => "MIT", :file => "LICENSE" }
@@ -17,7 +17,6 @@ Pod::Spec.new do |s|
s.libraries = "c++", "z"
s.requires_arc = true
s.ios.vendored_frameworks = 'Vendor/GPUImage.framework','Vendor/pili-librtmp.framework'
#s.dependency 'LMGPUImage'
#s.dependency 'pili-librtmp', '1.0.3.1'
s.dependency 'LMGPUImage'
s.dependency 'pili-librtmp', '1.0.3.1'
end
+2 -2
View File
@@ -2,8 +2,8 @@
// 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.
//
#if __has_include(<LFLiveKit/LFLiveKit.h>)
+11 -2
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>
@@ -127,7 +128,15 @@ typedef NS_ENUM(NSInteger,LFLiveCaptureTypeMask) {
*.*/
@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
+30 -14
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"
@@ -90,8 +90,8 @@
}
- (void)dealloc {
self.videoCaptureSource.running = NO;
self.audioCaptureSource.running = NO;
_videoCaptureSource.running = NO;
_audioCaptureSource.running = NO;
}
#pragma mark -- CustomMethod
@@ -100,7 +100,6 @@
_streamInfo = streamInfo;
_streamInfo.videoConfiguration = _videoConfiguration;
_streamInfo.audioConfiguration = _audioConfiguration;
_streamInfo.needDropFrame = (self.captureType & LFLiveCaptureMaskVideo || self.captureType & LFLiveInputMaskVideo) ? YES : NO;//< 有视频执行丢帧算法
[self.socket start];
}
@@ -110,15 +109,6 @@
self.socket = nil;
}
#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];
}
- (void)pushVideo:(nullable CVPixelBufferRef)pixelBuffer{
if(self.captureType & LFLiveInputMaskVideo){
if (self.uploading) [self.videoEncoder encodeVideoData:pixelBuffer timeStamp:NOW];
@@ -131,6 +121,15 @@
}
}
#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 audioData:(nullable NSData*)audioData {
if (self.uploading) [self.audioEncoder encodeAudioData:audioData timeStamp:NOW];
@@ -252,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;
}
+2 -2
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>
+11 -15
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"
@@ -98,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;
@@ -120,7 +121,11 @@ NSString *const LFAudioComponentFailedToCreateNotification = @"LFAudioComponentF
AudioOutputUnitStart(self.componetInstance);
});
} else {
self.isRunning = NO;
dispatch_async(self.taskQueue, ^{
self.isRunning = NO;
NSLog(@"MicrophoneSource: stopRunning");
AudioOutputUnitStop(self.componetInstance);
});
}
}
@@ -177,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);
});
@@ -191,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);
});
}
@@ -234,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];
+10 -2
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>
@@ -64,7 +64,15 @@
/*** 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
+52 -35
View File
@@ -2,8 +2,8 @@
// 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"
@@ -32,6 +32,8 @@
@property (nonatomic, strong) GPUImageUIElement *uiElementInput;
@property (nonatomic, strong) UIView *waterMarkContentView;
@property (nonatomic, strong) GPUImageMovieWriter *movieWriter;
@end
@implementation LFVideoCapture
@@ -48,6 +50,7 @@
[[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;
@@ -60,10 +63,10 @@
- (void)dealloc {
[UIApplication sharedApplication].idleTimerDisabled = NO;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.videoCamera stopCameraCapture];
if(self.gpuImageView){
[self.gpuImageView removeFromSuperview];
self.gpuImageView = nil;
[_videoCamera stopCameraCapture];
if(_gpuImageView){
[_gpuImageView removeFromSuperview];
_gpuImageView = nil;
}
}
@@ -72,22 +75,8 @@
- (GPUImageVideoCamera *)videoCamera{
if(!_videoCamera){
_videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:_configuration.avSessionPreset cameraPosition:AVCaptureDevicePositionFront];
UIInterfaceOrientation statusBar = [[UIApplication sharedApplication] statusBarOrientation];
if (self.configuration.landscape) {
if (statusBar != UIInterfaceOrientationLandscapeLeft && statusBar != UIInterfaceOrientationLandscapeRight) {
@throw [NSException exceptionWithName:@"当前设置方向出错" reason:@"LFLiveVideoConfiguration landscape error" userInfo:nil];
} else {
_videoCamera.outputImageOrientation = statusBar;
}
} else {
if (statusBar != UIInterfaceOrientationPortrait && statusBar != UIInterfaceOrientationPortraitUpsideDown) {
@throw [NSException exceptionWithName:@"当前设置方向出错" reason:@"LFLiveVideoConfiguration landscape error" userInfo:nil];
} else {
_videoCamera.outputImageOrientation = statusBar;
}
}
_videoCamera.horizontallyMirrorFrontFacingCamera = YES;
_videoCamera.outputImageOrientation = _configuration.outputImageOrientation;
_videoCamera.horizontallyMirrorFrontFacingCamera = NO;
_videoCamera.horizontallyMirrorRearFacingCamera = NO;
_videoCamera.frameRate = (int32_t)_configuration.videoFrameRate;
}
@@ -101,10 +90,12 @@
if (!_running) {
[UIApplication sharedApplication].idleTimerDisabled = NO;
[self.videoCamera stopCameraCapture];
if(self.saveLocalVideo) [self.movieWriter finishRecording];
} else {
[UIApplication sharedApplication].idleTimerDisabled = YES;
[self reloadFilter];
[self.videoCamera startCameraCapture];
if(self.saveLocalVideo) [self.movieWriter startRecording];
}
}
@@ -121,6 +112,7 @@
- (void)setCaptureDevicePosition:(AVCaptureDevicePosition)captureDevicePosition {
[self.videoCamera rotateCamera];
self.videoCamera.frameRate = (int32_t)_configuration.videoFrameRate;
[self reloadMirror];
}
- (AVCaptureDevicePosition)captureDevicePosition {
@@ -167,7 +159,6 @@
- (void)setMirror:(BOOL)mirror {
_mirror = mirror;
self.videoCamera.horizontallyMirrorFrontFacingCamera = mirror;
}
- (void)setBeautyFace:(BOOL)beautyFace{
@@ -265,6 +256,16 @@
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
- (void)processVideo:(GPUImageOutput *)output {
__weak typeof(self) _self = self;
@@ -277,7 +278,6 @@
}
}
- (void)reloadFilter{
[self.filter removeAllTargets];
[self.blendFilter removeAllTargets];
@@ -296,6 +296,9 @@
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);
@@ -311,11 +314,13 @@
[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];
@@ -323,6 +328,7 @@
[self.blendFilter forceProcessingAtSize:self.configuration.videoSize];
[self.uiElementInput forceProcessingAtSize:self.configuration.videoSize];
//< 输出数据
__weak typeof(self) _self = self;
[self.output setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime time) {
@@ -331,6 +337,14 @@
}
- (void)reloadMirror{
if(self.mirror && self.captureDevicePosition == AVCaptureDevicePositionFront){
self.videoCamera.horizontallyMirrorFrontFacingCamera = YES;
}else{
self.videoCamera.horizontallyMirrorFrontFacingCamera = NO;
}
}
#pragma mark Notification
- (void)willEnterBackground:(NSNotification *)notification {
@@ -349,17 +363,20 @@
- (void)statusBarChanged:(NSNotification *)notification {
NSLog(@"UIApplicationWillChangeStatusBarOrientationNotification. UserInfo: %@", notification.userInfo);
UIInterfaceOrientation statusBar = [[UIApplication sharedApplication] statusBarOrientation];
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;
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;
}
}
}
}
+2 -2
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>
+2 -2
View File
@@ -2,8 +2,8 @@
// LFH264VideoEncoder
// LFLiveKit
//
// Created by feng on 7/5/16.
// Copyright (c) 2014 zhanqi.tv. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#if __has_include(<LFLiveKit/LFLiveKit.h>)
+2 -2
View File
@@ -2,8 +2,8 @@
// LFH264VideoEncoder
// LFLiveKit
//
// Created by feng on 7/5/16.
// Copyright (c) 2014 zhanqi.tv. All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <CoreMedia/CoreMedia.h>
+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.
//
#if __has_include(<LFLiveKit/LFLiveKit.h>)
+16 -15
View File
@@ -2,8 +2,8 @@
// 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"
@@ -35,7 +35,7 @@
if (!aacBuf) {
aacBuf = malloc(_configuration.bufferLength);
}
#ifdef DEBUG
enabledWriteVideoFile = NO;
@@ -59,7 +59,7 @@
if (![self createAudioConvert]) {
return;
}
if(leftLength + audioData.length >= self.configuration.bufferLength){
///<  发送
NSInteger totalSize = leftLength + audioData.length;
@@ -75,12 +75,13 @@
[self encodeBuffer:p timeStamp:timeStamp];
p += self.configuration.bufferLength;
}
free(totalBuf);
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);
@@ -98,7 +99,7 @@
AudioBufferList buffers;
buffers.mNumberBuffers = 1;
buffers.mBuffers[0] = inBuffer;
// 初始化一个输出缓冲列表
AudioBufferList outBufferList;
@@ -132,7 +133,7 @@
}
- (void)stopEncoder {
}
#pragma mark -- CustomMethod
@@ -140,7 +141,7 @@
if (m_converter != nil) {
return TRUE;
}
AudioStreamBasicDescription inputFormat = {0};
inputFormat.mSampleRate = _configuration.audioSampleRate;
inputFormat.mFormatID = kAudioFormatLinearPCM;
@@ -150,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] = {
{
@@ -175,16 +176,16 @@
OSStatus result = AudioConverterNewSpecific(&inputFormat, &outputFormat, 2, requestedCodecs, &m_converter);;
UInt32 outputBitrate = _configuration.audioBitrate;
UInt32 propSize = sizeof(outputBitrate);
// UInt32 outputPacketSize = 0;
// UInt32 outputPacketSize = 0;
if(result == noErr) {
result = AudioConverterSetProperty(m_converter, kAudioConverterEncodeBitRate, propSize, &outputBitrate);
}
// if(result == noErr) {
// AudioConverterGetProperty(m_converter, kAudioConverterPropertyMaximumOutputPacketSize, &propSize, &outputPacketSize);
// }
// if(result == noErr) {
// AudioConverterGetProperty(m_converter, kAudioConverterPropertyMaximumOutputPacketSize, &propSize, &outputPacketSize);
// }
return YES;
}
+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.
//
#if __has_include(<LFLiveKit/LFLiveKit.h>)
+18 -18
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
@@ -32,20 +31,19 @@
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);
@@ -75,7 +73,7 @@
}
- (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);
@@ -99,8 +97,7 @@
#pragma mark -- LFVideoEncoder
- (void)encodeVideoData:(CVPixelBufferRef)pixelBuffer timeStamp:(uint64_t)timeStamp {
if (_isBackGround) return;
if(_isBackGround) return;
frameCount++;
CMTime presentationTimeStamp = CMTimeMake(frameCount, (int32_t)_configuration.videoFrameRate);
VTEncodeInfoFlags flags;
@@ -112,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 {
@@ -123,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;
}
+2 -2
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>
@@ -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>
@@ -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"
@@ -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,7 +51,7 @@ 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
///=============================================================================
@@ -64,7 +64,10 @@ typedef NS_ENUM (NSUInteger, LFLiveVideoQuality){
@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;
@@ -93,4 +96,7 @@ typedef NS_ENUM (NSUInteger, LFLiveVideoQuality){
///< ≈sde3分辨率
@property (nonatomic, assign, readonly) NSString *avSessionPreset;
///< 是否是横屏
@property (nonatomic, assign, readonly) BOOL landscape;
@end
@@ -2,8 +2,8 @@
// 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"
@@ -20,11 +20,11 @@
}
+ (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:{
@@ -131,9 +131,9 @@
}
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);
@@ -166,6 +166,10 @@
return avSessionPreset;
}
- (BOOL)landscape{
return (self.outputImageOrientation == UIInterfaceOrientationLandscapeLeft || self.outputImageOrientation == UIInterfaceOrientationLandscapeRight) ? YES : NO;
}
- (CGSize)videoSize{
if(_videoSizeRespectingAspectRatio){
return self.aspectRatioVideoSize;
@@ -249,7 +253,7 @@
break;
}
if(self.landscape){
if (self.landscape){
return CGSizeMake(videoSize.height, videoSize.width);
}
return videoSize;
@@ -275,7 +279,8 @@
[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"];
}
@@ -290,7 +295,8 @@
_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;
}
@@ -307,7 +313,8 @@
@(self.videoMinBitRate),
self.avSessionPreset,
@(self.sessionPreset),
@(self.landscape),
@(self.outputImageOrientation),
@(self.autorotate),
@(self.videoSizeRespectingAspectRatio)];
for (NSObject *value in values) {
@@ -333,7 +340,8 @@
object.videoMinBitRate == self.videoMinBitRate &&
[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;
}
}
@@ -357,7 +365,8 @@
[desc appendFormat:@" videoMinBitRate:%zi", self.videoMinBitRate];
[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;
}
+2 -2
View File
@@ -1,7 +1,7 @@
#if __has_include(<GPUImage/GPUImage.h>)
#import <GPUImage/GPUImage.h>
#elif __has_include("GPUImage/GPUImage.h")
#import "GPUImage/GPUImage.h"
#elif __has_include(<GPUImage/GPUImageFramework.h>)
#import <GPUImage/GPUImageFramework.h>
#else
#import "GPUImage.h"
#endif
+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.
//
#if __has_include(<LFLiveKit/LFLiveKit.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"
+2 -2
View File
@@ -2,8 +2,8 @@
// 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>
+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"
+6 -6
View File
@@ -2,9 +2,9 @@
// 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>
@@ -29,7 +29,9 @@ typedef NS_ENUM (NSUInteger, LFLiveState){
/// 已断开
LFLiveStop = 3,
/// 连接出错
LFLiveError = 4
LFLiveError = 4,
///  正在刷新
LFLiveRefresh = 5
};
typedef NS_ENUM (NSUInteger, LFLiveSocketErrorCode) {
@@ -53,7 +55,5 @@ typedef NS_ENUM (NSUInteger, LFLiveSocketErrorCode) {
@property (nonatomic, strong) LFLiveAudioConfiguration *audioConfiguration;
///视频配置
@property (nonatomic, strong) LFLiveVideoConfiguration *videoConfiguration;
///是否丢帧
@property (nonatomic, assign) BOOL needDropFrame;
@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"
+2 -2
View File
@@ -2,8 +2,8 @@
// 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.
//
#if __has_include(<LFLiveKit/LFLiveKit.h>)
+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.
//
#if __has_include(<LFLiveKit/LFLiveKit.h>)
+101 -80
View File
@@ -2,8 +2,8 @@
// 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"
@@ -16,7 +16,7 @@
#import "rtmp.h"
#endif
static const NSInteger RetryTimesBreaken = 20; ///< 重连1分钟 3秒一次 一共20次
static const NSInteger RetryTimesBreaken = 5; ///< 重连1分钟 3秒一次 一共20次
static const NSInteger RetryTimesMargin = 3;
@@ -28,7 +28,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);
@@ -112,12 +112,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];
});
}
@@ -131,12 +143,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];
}
@@ -148,74 +160,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;
});
}
@@ -237,18 +250,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);
@@ -287,19 +288,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;
}
@@ -491,36 +486,62 @@ 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;
LFStreamRTMPSocket *socket = (__bridge LFStreamRTMPSocket*)userData;
}
#pragma mark -- LFStreamingBufferDelegate
@@ -545,7 +566,7 @@ void ConnectionTimeCallback(PILI_CONNECTION_TIME *conn_time, void *userData) {
if (!_buffer) {
_buffer = [[LFStreamingBuffer alloc] init];
_buffer.delegate = self;
_buffer.needDropFrame = self.stream.needDropFrame;
}
return _buffer;
}
+2 -2
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>
+2 -4
View File
@@ -2,8 +2,8 @@
// 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>
@@ -34,8 +34,6 @@ typedef NS_ENUM (NSUInteger, LFLiveBuffferState) {
@interface LFStreamingBuffer : NSObject
/** The needDropFrame control Dynamic frame loss ,default is YES */
@property (nonatomic, assign) BOOL needDropFrame;
/** The delegate of the buffer. buffer callback */
@property (nullable, nonatomic, weak) id <LFStreamingBufferDelegate> delegate;
+20 -26
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
@@ -41,7 +41,6 @@ static const NSUInteger defaultSendBufferMaxCount = 600;///< 最大缓冲区为6
self.maxCount = defaultSendBufferMaxCount;
self.lastDropFrames = 0;
self.startTimer = NO;
self.needDropFrame = YES;
}
return self;
}
@@ -92,26 +91,21 @@ static const NSUInteger defaultSendBufferMaxCount = 600;///< 最大缓冲区为6
- (void)removeExpireFrame {
if (self.list.count < self.maxCount) return;
if(self.needDropFrame){
NSArray *pFrames = [self expirePFrames];///< 第一个P到第一个I之间的p帧
self.lastDropFrames += [pFrames count];
if (pFrames && pFrames.count > 0) {
[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];
}else{
[self.list lfPopFirstObject];
NSArray *pFrames = [self expirePFrames];///< 第一个P到第一个I之间的p帧
self.lastDropFrames += [pFrames count];
if (pFrames && pFrames.count > 0) {
[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];
}
- (NSArray *)expirePFrames {
@@ -161,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];
@@ -176,7 +170,7 @@ NSInteger frameDataCompare(id obj1, id obj2, void *context){
if (decreaseCount >= self.callBackInterval) {
return LFLiveBuffferDecline;
}
return LFLiveBuffferUnknown;
}
@@ -210,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) {
+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"
@@ -25,30 +25,13 @@
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 */; };
84D8B4681D75783F00752B56 /* GPUImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4661D75783F00752B56 /* GPUImage.framework */; };
84D8B4CF1D757F0700752B56 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4CE1D757F0700752B56 /* libstdc++.tbd */; };
84D8B5541D76822C00752B56 /* pili-librtmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B5531D76822C00752B56 /* pili-librtmp.framework */; };
84D8B5F41D768B9E00752B56 /* LFLiveKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B5F11D768B8300752B56 /* LFLiveKit.framework */; };
BC8B37EEE1CEEF9B5614DC91 /* libPods-LFLiveKitDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B1CCEEE06FCFAF75D105A51 /* libPods-LFLiveKitDemo.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
84D8B5F01D768B8300752B56 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84D8B5EC1D768B8300752B56 /* LFLiveKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 84D8B3901D7574D600752B56;
remoteInfo = LFLiveKit;
};
84D8B5F21D768B9700752B56 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84D8B5EC1D768B8300752B56 /* LFLiveKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 84D8B38F1D7574D600752B56;
remoteInfo = LFLiveKit;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
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>"; };
@@ -74,10 +57,8 @@
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>"; };
84D8B4661D75783F00752B56 /* GPUImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GPUImage.framework; path = ../Vendor/GPUImage.framework; sourceTree = "<group>"; };
84D8B4CE1D757F0700752B56 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; };
84D8B5531D76822C00752B56 /* pili-librtmp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "pili-librtmp.framework"; path = "../Vendor/pili-librtmp.framework"; sourceTree = "<group>"; };
84D8B5EC1D768B8300752B56 /* LFLiveKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = LFLiveKit.xcodeproj; path = ../FrameWork/LFLiveKit.xcodeproj; sourceTree = "<group>"; };
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 */
@@ -85,25 +66,30 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
84D8B5F41D768B9E00752B56 /* LFLiveKit.framework in Frameworks */,
84D8B5541D76822C00752B56 /* pili-librtmp.framework in Frameworks */,
84D8B4CF1D757F0700752B56 /* libstdc++.tbd in Frameworks */,
84D8B4681D75783F00752B56 /* GPUImage.framework in Frameworks */,
BC8B37EEE1CEEF9B5614DC91 /* libPods-LFLiveKitDemo.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
65E0CF98FF954863E543A0E1 /* Frameworks */ = {
isa = PBXGroup;
children = (
5B1CCEEE06FCFAF75D105A51 /* libPods-LFLiveKitDemo.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
84D8B41D1D75778B00752B56 = {
isa = PBXGroup;
children = (
84D8B5EC1D768B8300752B56 /* LFLiveKit.xcodeproj */,
84D8B5531D76822C00752B56 /* pili-librtmp.framework */,
84D8B4CE1D757F0700752B56 /* libstdc++.tbd */,
84D8B4661D75783F00752B56 /* GPUImage.framework */,
84D8B4281D75778B00752B56 /* LFLiveKitDemo */,
84D8B4271D75778B00752B56 /* Products */,
F3E359B8A7561F963C47A62F /* Pods */,
65E0CF98FF954863E543A0E1 /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -170,12 +156,13 @@
path = images;
sourceTree = "<group>";
};
84D8B5ED1D768B8300752B56 /* Products */ = {
F3E359B8A7561F963C47A62F /* Pods */ = {
isa = PBXGroup;
children = (
84D8B5F11D768B8300752B56 /* LFLiveKit.framework */,
289A9C4510CD7EA6F4CE9897 /* Pods-LFLiveKitDemo.debug.xcconfig */,
96E1231310083A3881AD2AB6 /* Pods-LFLiveKitDemo.release.xcconfig */,
);
name = Products;
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
@@ -185,14 +172,16 @@
isa = PBXNativeTarget;
buildConfigurationList = 84D8B43D1D75778B00752B56 /* Build configuration list for PBXNativeTarget "LFLiveKitDemo" */;
buildPhases = (
A819C09CC049A57DC5C97E12 /* 📦 Check Pods Manifest.lock */,
84D8B4221D75778B00752B56 /* Sources */,
84D8B4231D75778B00752B56 /* Frameworks */,
84D8B4241D75778B00752B56 /* Resources */,
883533331BE4DCC0DB5075CF /* 📦 Embed Pods Frameworks */,
4CC4C37B93D109913E475307 /* 📦 Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
84D8B5F31D768B9700752B56 /* PBXTargetDependency */,
);
name = LFLiveKitDemo;
productName = LFLiveKitDemo;
@@ -210,6 +199,7 @@
TargetAttributes = {
84D8B4251D75778B00752B56 = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = G497YX6CBT;
};
};
};
@@ -224,12 +214,6 @@
mainGroup = 84D8B41D1D75778B00752B56;
productRefGroup = 84D8B4271D75778B00752B56 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 84D8B5ED1D768B8300752B56 /* Products */;
ProjectRef = 84D8B5EC1D768B8300752B56 /* LFLiveKit.xcodeproj */;
},
);
projectRoot = "";
targets = (
84D8B4251D75778B00752B56 /* LFLiveKitDemo */,
@@ -237,16 +221,6 @@
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
84D8B5F11D768B8300752B56 /* LFLiveKit.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = LFLiveKit.framework;
remoteRef = 84D8B5F01D768B8300752B56 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
84D8B4241D75778B00752B56 /* Resources */ = {
isa = PBXResourcesBuildPhase;
@@ -269,6 +243,54 @@
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
4CC4C37B93D109913E475307 /* 📦 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-LFLiveKitDemo/Pods-LFLiveKitDemo-resources.sh\"\n";
showEnvVarsInLog = 0;
};
883533331BE4DCC0DB5075CF /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
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 */
84D8B4221D75778B00752B56 /* Sources */ = {
isa = PBXSourcesBuildPhase;
@@ -285,14 +307,6 @@
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
84D8B5F31D768B9700752B56 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = LFLiveKit;
targetProxy = 84D8B5F21D768B9700752B56 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
84D8B4321D75778B00752B56 /* Main.storyboard */ = {
isa = PBXVariantGroup;
@@ -397,38 +411,36 @@
};
84D8B43E1D75778B00752B56 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 289A9C4510CD7EA6F4CE9897 /* Pods-LFLiveKitDemo.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../Vendor\"/**",
);
HEADER_SEARCH_PATHS = "";
DEVELOPMENT_TEAM = G497YX6CBT;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = LFLiveKitDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "";
OTHER_LDFLAGS = "-all_load";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKitDemo;
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LaiFeng;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
84D8B43F1D75778B00752B56 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 96E1231310083A3881AD2AB6 /* Pods-LFLiveKitDemo.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../Vendor\"/**",
);
HEADER_SEARCH_PATHS = "";
DEVELOPMENT_TEAM = G497YX6CBT;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = LFLiveKitDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "";
OTHER_LDFLAGS = "-all_load";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKitDemo;
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LaiFeng;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
+4 -1
View File
@@ -26,13 +26,16 @@
<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>
+13 -4
View File
@@ -9,7 +9,7 @@
#import "LFLivePreview.h"
#import "UIControl+YYAdd.h"
#import "UIView+YYAdd.h"
#import <LFLiveKit/LFLiveKit.h>
#import "LFLiveKit.h"
inline static NSString *formatedSpeed(float bytes, float elapsed_milli) {
if (elapsed_milli <= 0) {
@@ -157,13 +157,14 @@ inline static NSString *formatedSpeed(float bytes, float elapsed_milli) {
/***  默认分辨率368 640 音频:44.1 iphone6以上48 双声道 方向竖屏 ***/
LFLiveVideoConfiguration *videoConfiguration = [LFLiveVideoConfiguration new];
videoConfiguration.videoSize = CGSizeMake(360, 640);
videoConfiguration.videoSize = CGSizeMake(640, 360);
videoConfiguration.videoBitRate = 800*1024;
videoConfiguration.videoMaxBitRate = 1000*1024;
videoConfiguration.videoMinBitRate = 500*1024;
videoConfiguration.videoFrameRate = 24;
videoConfiguration.videoMaxKeyframeInterval = 48;
videoConfiguration.landscape = NO;
videoConfiguration.outputImageOrientation = UIInterfaceOrientationLandscapeLeft;
videoConfiguration.autorotate = NO;
videoConfiguration.sessionPreset = LFCaptureSessionPreset720x1280;
_session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:videoConfiguration captureType:LFLiveCaptureDefaultMask];
@@ -254,11 +255,19 @@ inline static NSString *formatedSpeed(float bytes, float elapsed_milli) {
_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;
_session.warterMarkView = imageView;*/
}
return _session;
+1 -1
View File
@@ -22,7 +22,7 @@
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
+6
View File
@@ -0,0 +1,6 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios,'7.0'
target “LFLiveKitDemo” do
pod 'LFLiveKit', :path => '../.'
end
@@ -20,30 +20,13 @@
84D8B4B11D757DBB00752B56 /* camra_preview@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4A91D757DBB00752B56 /* camra_preview@3x.png */; };
84D8B4B21D757DBB00752B56 /* close_preview@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4AA1D757DBB00752B56 /* close_preview@2x.png */; };
84D8B4B31D757DBB00752B56 /* close_preview@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84D8B4AB1D757DBB00752B56 /* close_preview@3x.png */; };
84D8B4BA1D757DED00752B56 /* GPUImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4B81D757DED00752B56 /* GPUImage.framework */; };
84D8B4BD1D757E0E00752B56 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4BC1D757E0E00752B56 /* libstdc++.tbd */; };
84D8B5571D76824700752B56 /* pili-librtmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B5561D76824700752B56 /* pili-librtmp.framework */; };
84D8B5FE1D768BBE00752B56 /* LFLiveKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B5FB1D768BB200752B56 /* LFLiveKit.framework */; };
9CA0546A1BD4E74670872B9B /* libPods-LFLiveKitSwiftDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E0C4364E65B82DECF3326D9 /* libPods-LFLiveKitSwiftDemo.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
84D8B5FA1D768BB200752B56 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84D8B5F61D768BB200752B56 /* LFLiveKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 84D8B3901D7574D600752B56;
remoteInfo = LFLiveKit;
};
84D8B5FC1D768BB800752B56 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84D8B5F61D768BB200752B56 /* LFLiveKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 84D8B38F1D7574D600752B56;
remoteInfo = LFLiveKit;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
4E0C4364E65B82DECF3326D9 /* libPods-LFLiveKitSwiftDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LFLiveKitSwiftDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; };
7265B07B4B6CEE8ECE8F7A63 /* Pods-LFLiveKitSwiftDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LFLiveKitSwiftDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LFLiveKitSwiftDemo/Pods-LFLiveKitSwiftDemo.debug.xcconfig"; sourceTree = "<group>"; };
84D8B4881D757D4000752B56 /* LFLiveKitSwiftDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LFLiveKitSwiftDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
84D8B48B1D757D4000752B56 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
84D8B48D1D757D4000752B56 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
@@ -59,11 +42,8 @@
84D8B4A91D757DBB00752B56 /* camra_preview@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camra_preview@3x.png"; sourceTree = "<group>"; };
84D8B4AA1D757DBB00752B56 /* close_preview@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "close_preview@2x.png"; sourceTree = "<group>"; };
84D8B4AB1D757DBB00752B56 /* close_preview@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "close_preview@3x.png"; sourceTree = "<group>"; };
84D8B4B41D757DCC00752B56 /* LFLiveKitSwiftDemo-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "LFLiveKitSwiftDemo-Bridging-Header.h"; sourceTree = "<group>"; };
84D8B4B81D757DED00752B56 /* GPUImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GPUImage.framework; path = ../Vendor/GPUImage.framework; sourceTree = "<group>"; };
84D8B4BC1D757E0E00752B56 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; };
84D8B5561D76824700752B56 /* pili-librtmp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "pili-librtmp.framework"; path = "../Vendor/pili-librtmp.framework"; sourceTree = "<group>"; };
84D8B5F61D768BB200752B56 /* LFLiveKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = LFLiveKit.xcodeproj; path = ../FrameWork/LFLiveKit.xcodeproj; sourceTree = "<group>"; };
DAC498DB742E949DED005ECE /* Pods-LFLiveKitSwiftDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LFLiveKitSwiftDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-LFLiveKitSwiftDemo/Pods-LFLiveKitSwiftDemo.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -71,25 +51,30 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
84D8B5FE1D768BBE00752B56 /* LFLiveKit.framework in Frameworks */,
84D8B5571D76824700752B56 /* pili-librtmp.framework in Frameworks */,
84D8B4BD1D757E0E00752B56 /* libstdc++.tbd in Frameworks */,
84D8B4BA1D757DED00752B56 /* GPUImage.framework in Frameworks */,
9CA0546A1BD4E74670872B9B /* libPods-LFLiveKitSwiftDemo.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
23FA2B0543E0C2A8E7C84D9E /* Frameworks */ = {
isa = PBXGroup;
children = (
4E0C4364E65B82DECF3326D9 /* libPods-LFLiveKitSwiftDemo.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
84D8B47F1D757D4000752B56 = {
isa = PBXGroup;
children = (
84D8B5F61D768BB200752B56 /* LFLiveKit.xcodeproj */,
84D8B5561D76824700752B56 /* pili-librtmp.framework */,
84D8B4BC1D757E0E00752B56 /* libstdc++.tbd */,
84D8B4B81D757DED00752B56 /* GPUImage.framework */,
84D8B48A1D757D4000752B56 /* LFLiveKitSwiftDemo */,
84D8B4891D757D4000752B56 /* Products */,
B19B532AA669846CC85D50E3 /* Pods */,
23FA2B0543E0C2A8E7C84D9E /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -106,7 +91,6 @@
children = (
84D8B48B1D757D4000752B56 /* AppDelegate.swift */,
84D8B48D1D757D4000752B56 /* ViewController.swift */,
84D8B4B41D757DCC00752B56 /* LFLiveKitSwiftDemo-Bridging-Header.h */,
84D8B48F1D757D4000752B56 /* Main.storyboard */,
84D8B4A31D757DBB00752B56 /* images */,
84D8B4921D757D4000752B56 /* Assets.xcassets */,
@@ -131,12 +115,13 @@
path = images;
sourceTree = "<group>";
};
84D8B5F71D768BB200752B56 /* Products */ = {
B19B532AA669846CC85D50E3 /* Pods */ = {
isa = PBXGroup;
children = (
84D8B5FB1D768BB200752B56 /* LFLiveKit.framework */,
7265B07B4B6CEE8ECE8F7A63 /* Pods-LFLiveKitSwiftDemo.debug.xcconfig */,
DAC498DB742E949DED005ECE /* Pods-LFLiveKitSwiftDemo.release.xcconfig */,
);
name = Products;
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
@@ -146,14 +131,16 @@
isa = PBXNativeTarget;
buildConfigurationList = 84D8B49A1D757D4000752B56 /* Build configuration list for PBXNativeTarget "LFLiveKitSwiftDemo" */;
buildPhases = (
FC46EAD69B9F095AB7372DB6 /* 📦 Check Pods Manifest.lock */,
84D8B4841D757D4000752B56 /* Sources */,
84D8B4851D757D4000752B56 /* Frameworks */,
84D8B4861D757D4000752B56 /* Resources */,
951756CA4F11963EE3622ADB /* 📦 Embed Pods Frameworks */,
1D8289CE7990A09D5E67FA15 /* 📦 Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
84D8B5FD1D768BB800752B56 /* PBXTargetDependency */,
);
name = LFLiveKitSwiftDemo;
productName = LFLiveKitSwiftDemo;
@@ -172,6 +159,8 @@
TargetAttributes = {
84D8B4871D757D4000752B56 = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = G497YX6CBT;
LastSwiftMigration = 0800;
};
};
};
@@ -186,12 +175,6 @@
mainGroup = 84D8B47F1D757D4000752B56;
productRefGroup = 84D8B4891D757D4000752B56 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 84D8B5F71D768BB200752B56 /* Products */;
ProjectRef = 84D8B5F61D768BB200752B56 /* LFLiveKit.xcodeproj */;
},
);
projectRoot = "";
targets = (
84D8B4871D757D4000752B56 /* LFLiveKitSwiftDemo */,
@@ -199,16 +182,6 @@
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
84D8B5FB1D768BB200752B56 /* LFLiveKit.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = LFLiveKit.framework;
remoteRef = 84D8B5FA1D768BB200752B56 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
84D8B4861D757D4000752B56 /* Resources */ = {
isa = PBXResourcesBuildPhase;
@@ -230,6 +203,54 @@
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
1D8289CE7990A09D5E67FA15 /* 📦 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-LFLiveKitSwiftDemo/Pods-LFLiveKitSwiftDemo-resources.sh\"\n";
showEnvVarsInLog = 0;
};
951756CA4F11963EE3622ADB /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LFLiveKitSwiftDemo/Pods-LFLiveKitSwiftDemo-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
FC46EAD69B9F095AB7372DB6 /* 📦 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 */
84D8B4841D757D4000752B56 /* Sources */ = {
isa = PBXSourcesBuildPhase;
@@ -242,14 +263,6 @@
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
84D8B5FD1D768BB800752B56 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = LFLiveKit;
targetProxy = 84D8B5FC1D768BB800752B56 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
84D8B48F1D757D4000752B56 /* Main.storyboard */ = {
isa = PBXVariantGroup;
@@ -355,29 +368,41 @@
};
84D8B49B1D757D4000752B56 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7265B07B4B6CEE8ECE8F7A63 /* Pods-LFLiveKitSwiftDemo.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/../Vendor\"/**";
DEVELOPMENT_TEAM = G497YX6CBT;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = LFLiveKitSwiftDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKitSwiftDemo;
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-all_load";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LaiFeng;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "LFLiveKitSwiftDemo/LFLiveKitSwiftDemo-Bridging-Header.h";
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
84D8B49C1D757D4000752B56 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = DAC498DB742E949DED005ECE /* Pods-LFLiveKitSwiftDemo.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/../Vendor\"/**";
DEVELOPMENT_TEAM = G497YX6CBT;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = LFLiveKitSwiftDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKitSwiftDemo;
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-all_load";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LaiFeng;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "LFLiveKitSwiftDemo/LFLiveKitSwiftDemo-Bridging-Header.h";
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -14,30 +14,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(application: UIApplication) {
func applicationWillResignActive(_ application: UIApplication) {
// 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.
}
func applicationDidEnterBackground(application: UIApplication) {
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@@ -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/LFLiveKit.h>
#endif
@@ -7,6 +7,7 @@
//
import UIKit
import LFLiveKit
class ViewController: UIViewController, LFLiveSessionDelegate {
@@ -15,7 +16,7 @@ class ViewController: UIViewController, LFLiveSessionDelegate {
// Do any additional setup after loading the view, typically from a nib.
self.requestAccessForVideo()
self.requestAccessForAudio()
self.view.backgroundColor = UIColor.clearColor()
self.view.backgroundColor = UIColor.clear
self.view.addSubview(containerView)
containerView.addSubview(stateLabel)
containerView.addSubview(closeButton)
@@ -78,15 +79,15 @@ class ViewController: UIViewController, LFLiveSessionDelegate {
//MARK: - Callbacks
//
func liveSession(session: LFLiveSession?, debugInfo: LFLiveDebug?) {
func liveSession(_ session: LFLiveSession?, debugInfo: LFLiveDebug?) {
print("debugInfo: \(debugInfo?.currentBandwidth)")
}
func liveSession(session: LFLiveSession?, errorCode: LFLiveSocketErrorCode) {
func liveSession(_ session: LFLiveSession?, errorCode: LFLiveSocketErrorCode) {
print("errorCode: \(errorCode.rawValue)")
}
func liveSession(session: LFLiveSession?, liveStateDidChange state: LFLiveState) {
func liveSession(_ session: LFLiveSession?, liveStateDidChange state: LFLiveState) {
print("liveStateDidChange: \(state.rawValue)")
switch state {
case LFLiveState.Ready:
@@ -104,42 +105,39 @@ class ViewController: UIViewController, LFLiveSessionDelegate {
case LFLiveState.Stop:
stateLabel.text = "未连接"
break;
default:
stateLabel.text = "未知"
break;
}
}
//MARK: - Events
//
func didTappedStartLiveButton(button: UIButton) -> Void {
startLiveButton.selected = !startLiveButton.selected;
if (startLiveButton.selected) {
startLiveButton.setTitle("结束直播", forState: UIControlState.Normal)
func didTappedStartLiveButton(_ button: UIButton) -> Void {
startLiveButton.isSelected = !startLiveButton.isSelected;
if (startLiveButton.isSelected) {
startLiveButton.setTitle("结束直播", for: UIControlState())
let stream = LFLiveStreamInfo()
stream.url = "rtmp://30.96.179.95:1935/live/1234"
stream.url = "rtmp://live.hkstv.hk.lxdns.com:1935/live/stream153"
session.startLive(stream)
} else {
startLiveButton.setTitle("开始直播", forState: UIControlState.Normal)
startLiveButton.setTitle("开始直播", for: UIControlState())
session.stopLive()
}
}
//
func didTappedBeautyButton(button: UIButton) -> Void {
func didTappedBeautyButton(_ button: UIButton) -> Void {
session.beautyFace = !session.beautyFace;
beautyButton.selected = !session.beautyFace;
}
//
func didTappedCameraButton(button: UIButton) -> Void {
func didTappedCameraButton(_ button: UIButton) -> Void {
let devicePositon = session.captureDevicePosition;
session.captureDevicePosition = (devicePositon == AVCaptureDevicePosition.Back) ? AVCaptureDevicePosition.Front : AVCaptureDevicePosition.Back;
}
//
func didTappedCloseButton(button: UIButton) -> Void {
func didTappedCloseButton(_ button: UIButton) -> Void {
}
@@ -148,7 +146,7 @@ class ViewController: UIViewController, LFLiveSessionDelegate {
//  368 640 44.1 iphone648
lazy var session: LFLiveSession = {
let audioConfiguration = LFLiveAudioConfiguration.defaultConfiguration()
let videoConfiguration = LFLiveVideoConfiguration.defaultConfigurationForQuality(LFLiveVideoQuality.Low3, landscape: false)
let videoConfiguration = LFLiveVideoConfiguration.defaultConfigurationForQuality(LFLiveVideoQuality.Low3)
let session = LFLiveSession(audioConfiguration: audioConfiguration, videoConfiguration: videoConfiguration)
session?.delegate = self
@@ -159,8 +157,8 @@ class ViewController: UIViewController, LFLiveSessionDelegate {
//
lazy var containerView: UIView = {
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
containerView.backgroundColor = UIColor.clearColor()
containerView.autoresizingMask = [UIViewAutoresizing.FlexibleHeight, UIViewAutoresizing.FlexibleHeight]
containerView.backgroundColor = UIColor.clear
containerView.autoresizingMask = [UIViewAutoresizing.flexibleHeight, UIViewAutoresizing.flexibleHeight]
return containerView
}()
@@ -168,33 +166,33 @@ class ViewController: UIViewController, LFLiveSessionDelegate {
lazy var stateLabel: UILabel = {
let stateLabel = UILabel(frame: CGRect(x: 20, y: 20, width: 80, height: 40))
stateLabel.text = "未连接"
stateLabel.textColor = UIColor.whiteColor()
stateLabel.font = UIFont.systemFontOfSize(14)
stateLabel.textColor = UIColor.white
stateLabel.font = UIFont.systemFont(ofSize: 14)
return stateLabel
}()
//
lazy var closeButton: UIButton = {
let closeButton = UIButton(frame: CGRect(x: self.view.frame.width - 10 - 44, y: 20, width: 44, height: 44))
closeButton.setImage(UIImage(named: "close_preview"), forState: UIControlState.Normal)
closeButton.addTarget(self, action: #selector(didTappedCloseButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
closeButton.setImage(UIImage(named: "close_preview"), for: UIControlState())
closeButton.addTarget(self, action: #selector(didTappedCloseButton(_:)), for: UIControlEvents.touchUpInside)
return closeButton
}()
//
lazy var cameraButton: UIButton = {
let cameraButton = UIButton(frame: CGRect(x: self.view.frame.width - 54 * 2, y: 20, width: 44, height: 44))
cameraButton.setImage(UIImage(named: "camra_preview"), forState: UIControlState.Normal)
cameraButton.addTarget(self, action: #selector(didTappedCameraButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
cameraButton.setImage(UIImage(named: "camra_preview"), for: UIControlState())
cameraButton.addTarget(self, action: #selector(didTappedCameraButton(_:)), for: UIControlEvents.touchUpInside)
return cameraButton
}()
//
lazy var beautyButton: UIButton = {
let beautyButton = UIButton(frame: CGRect(x: self.view.frame.width - 54 * 3, y: 20, width: 44, height: 44))
beautyButton.setImage(UIImage(named: "camra_preview"), forState: UIControlState.Selected)
beautyButton.setImage(UIImage(named: "camra_beauty_close"), forState: UIControlState.Normal)
beautyButton.addTarget(self, action: #selector(didTappedBeautyButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
beautyButton.setImage(UIImage(named: "camra_preview"), for: UIControlState.selected)
beautyButton.setImage(UIImage(named: "camra_beauty_close"), for: UIControlState())
beautyButton.addTarget(self, action: #selector(didTappedBeautyButton(_:)), for: UIControlEvents.touchUpInside)
return beautyButton
}()
@@ -202,20 +200,20 @@ class ViewController: UIViewController, LFLiveSessionDelegate {
lazy var startLiveButton: UIButton = {
let startLiveButton = UIButton(frame: CGRect(x: 30, y: self.view.frame.height - 50, width: self.view.frame.width - 10 - 44, height: 44))
startLiveButton.layer.cornerRadius = 22
startLiveButton.setTitleColor(UIColor.blackColor(), forState:UIControlState.Normal)
startLiveButton.setTitle("开始直播", forState: UIControlState.Normal)
startLiveButton.titleLabel!.font = UIFont.systemFontOfSize(14)
startLiveButton.setTitleColor(UIColor.black, for:UIControlState())
startLiveButton.setTitle("开始直播", for: UIControlState())
startLiveButton.titleLabel!.font = UIFont.systemFont(ofSize: 14)
startLiveButton.backgroundColor = UIColor(colorLiteralRed: 50, green: 32, blue: 245, alpha: 1)
startLiveButton.addTarget(self, action: #selector(didTappedStartLiveButton(_:)), forControlEvents: UIControlEvents.TouchUpInside)
startLiveButton.addTarget(self, action: #selector(didTappedStartLiveButton(_:)), for: UIControlEvents.touchUpInside)
return startLiveButton
}()
//
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait
}
override func shouldAutorotate() -> Bool {
override var shouldAutorotate : Bool {
return true
}
}
+6
View File
@@ -0,0 +1,6 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios,'7.0'
target “LFLiveKitSwiftDemo” do
pod 'LFLiveKit', :path => '../.'
end
+52 -49
View File
@@ -66,71 +66,74 @@ LFLiveKit
* VideoToolbox
* AudioToolbox
* libz
* libstdc++
## 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;
}
- (LFLiveSession*)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";
[self.session startLive:streamInfo];
}
- (void)startLive {
LFLiveStreamInfo *streamInfo = [LFLiveStreamInfo new];
streamInfo.url = @"your server rtmp url";
[self.session startLive:streamInfo];
}
- (void)stopLive {
[self.session stopLive];
}
//MARK: - CallBack:
- (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;
- (void)stopLive {
[self.session stopLive];
}
//MARK: - CallBack:
- (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 in [ProjectName]-Bridging-Header.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!
}()
//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!
}()
//MARK: - Event
func startLive() -> Void {
let stream = LFLiveStreamInfo()
stream.url = "your server rtmp url";
session.startLive(stream)
}
//MARK: - Event
func startLive() -> Void {
let stream = LFLiveStreamInfo()
stream.url = "your server rtmp url";
session.startLive(stream)
}
func stopLive() -> Void {
session.stopLive()
}
//MARK: - Callback
func liveSession(session: LFLiveSession?, debugInfo: LFLiveDebug?)
func liveSession(session: LFLiveSession?, errorCode: LFLiveSocketErrorCode)
func liveSession(session: LFLiveSession?, liveStateDidChange state: LFLiveState)
func stopLive() -> Void {
session.stopLive()
}
//MARK: - Callback
func liveSession(session: LFLiveSession?, debugInfo: LFLiveDebug?)
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
Binary file not shown.
-42
View File
@@ -1,42 +0,0 @@
// This is Jeff LaMarche's GLProgram OpenGL shader wrapper class from his OpenGL ES 2.0 book.
// A description of this can be found at his page on the topic:
// http://iphonedevelopment.blogspot.com/2010/11/opengl-es-20-for-ios-chapter-4.html
// I've extended this to be able to take programs as NSStrings in addition to files, for baked-in shaders
#import <Foundation/Foundation.h>
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
#else
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
#endif
@interface GLProgram : NSObject
{
NSMutableArray *attributes;
NSMutableArray *uniforms;
GLuint program,
vertShader,
fragShader;
}
@property(readwrite, nonatomic) BOOL initialized;
@property(readwrite, copy, nonatomic) NSString *vertexShaderLog;
@property(readwrite, copy, nonatomic) NSString *fragmentShaderLog;
@property(readwrite, copy, nonatomic) NSString *programLog;
- (id)initWithVertexShaderString:(NSString *)vShaderString
fragmentShaderString:(NSString *)fShaderString;
- (id)initWithVertexShaderString:(NSString *)vShaderString
fragmentShaderFilename:(NSString *)fShaderFilename;
- (id)initWithVertexShaderFilename:(NSString *)vShaderFilename
fragmentShaderFilename:(NSString *)fShaderFilename;
- (void)addAttribute:(NSString *)attributeName;
- (GLuint)attributeIndex:(NSString *)attributeName;
- (GLuint)uniformIndex:(NSString *)uniformName;
- (BOOL)link;
- (void)use;
- (void)validate;
@end
-170
View File
@@ -1,170 +0,0 @@
#import "GLProgram.h"
// Base classes
#import "GPUImageContext.h"
#import "GPUImageOutput.h"
#import "GPUImageView.h"
#import "GPUImageVideoCamera.h"
#import "GPUImageStillCamera.h"
#import "GPUImageMovie.h"
#import "GPUImagePicture.h"
#import "GPUImageRawDataInput.h"
#import "GPUImageRawDataOutput.h"
#import "GPUImageMovieWriter.h"
#import "GPUImageFilterPipeline.h"
#import "GPUImageTextureOutput.h"
#import "GPUImageFilterGroup.h"
#import "GPUImageTextureInput.h"
#import "GPUImageUIElement.h"
#import "GPUImageBuffer.h"
#import "GPUImageFramebuffer.h"
#import "GPUImageFramebufferCache.h"
// Filters
#import "GPUImageFilter.h"
#import "GPUImageTwoInputFilter.h"
#import "GPUImagePixellateFilter.h"
#import "GPUImagePixellatePositionFilter.h"
#import "GPUImageSepiaFilter.h"
#import "GPUImageColorInvertFilter.h"
#import "GPUImageSaturationFilter.h"
#import "GPUImageContrastFilter.h"
#import "GPUImageExposureFilter.h"
#import "GPUImageBrightnessFilter.h"
#import "GPUImageLevelsFilter.h"
#import "GPUImageSharpenFilter.h"
#import "GPUImageGammaFilter.h"
#import "GPUImageSobelEdgeDetectionFilter.h"
#import "GPUImageSketchFilter.h"
#import "GPUImageToonFilter.h"
#import "GPUImageSmoothToonFilter.h"
#import "GPUImageMultiplyBlendFilter.h"
#import "GPUImageDissolveBlendFilter.h"
#import "GPUImageKuwaharaFilter.h"
#import "GPUImageKuwaharaRadius3Filter.h"
#import "GPUImageVignetteFilter.h"
#import "GPUImageGaussianBlurFilter.h"
#import "GPUImageGaussianBlurPositionFilter.h"
#import "GPUImageGaussianSelectiveBlurFilter.h"
#import "GPUImageOverlayBlendFilter.h"
#import "GPUImageDarkenBlendFilter.h"
#import "GPUImageLightenBlendFilter.h"
#import "GPUImageSwirlFilter.h"
#import "GPUImageSourceOverBlendFilter.h"
#import "GPUImageColorBurnBlendFilter.h"
#import "GPUImageColorDodgeBlendFilter.h"
#import "GPUImageScreenBlendFilter.h"
#import "GPUImageExclusionBlendFilter.h"
#import "GPUImageDifferenceBlendFilter.h"
#import "GPUImageSubtractBlendFilter.h"
#import "GPUImageHardLightBlendFilter.h"
#import "GPUImageSoftLightBlendFilter.h"
#import "GPUImageColorBlendFilter.h"
#import "GPUImageHueBlendFilter.h"
#import "GPUImageSaturationBlendFilter.h"
#import "GPUImageLuminosityBlendFilter.h"
#import "GPUImageCropFilter.h"
#import "GPUImageGrayscaleFilter.h"
#import "GPUImageTransformFilter.h"
#import "GPUImageChromaKeyBlendFilter.h"
#import "GPUImageHazeFilter.h"
#import "GPUImageLuminanceThresholdFilter.h"
#import "GPUImagePosterizeFilter.h"
#import "GPUImageBoxBlurFilter.h"
#import "GPUImageAdaptiveThresholdFilter.h"
#import "GPUImageSolarizeFilter.h"
#import "GPUImageUnsharpMaskFilter.h"
#import "GPUImageBulgeDistortionFilter.h"
#import "GPUImagePinchDistortionFilter.h"
#import "GPUImageCrosshatchFilter.h"
#import "GPUImageCGAColorspaceFilter.h"
#import "GPUImagePolarPixellateFilter.h"
#import "GPUImageStretchDistortionFilter.h"
#import "GPUImagePerlinNoiseFilter.h"
#import "GPUImageJFAVoronoiFilter.h"
#import "GPUImageVoronoiConsumerFilter.h"
#import "GPUImageMosaicFilter.h"
#import "GPUImageTiltShiftFilter.h"
#import "GPUImage3x3ConvolutionFilter.h"
#import "GPUImageEmbossFilter.h"
#import "GPUImageCannyEdgeDetectionFilter.h"
#import "GPUImageThresholdEdgeDetectionFilter.h"
#import "GPUImageMaskFilter.h"
#import "GPUImageHistogramFilter.h"
#import "GPUImageHistogramGenerator.h"
#import "GPUImageHistogramEqualizationFilter.h"
#import "GPUImagePrewittEdgeDetectionFilter.h"
#import "GPUImageXYDerivativeFilter.h"
#import "GPUImageHarrisCornerDetectionFilter.h"
#import "GPUImageAlphaBlendFilter.h"
#import "GPUImageNormalBlendFilter.h"
#import "GPUImageNonMaximumSuppressionFilter.h"
#import "GPUImageRGBFilter.h"
#import "GPUImageMedianFilter.h"
#import "GPUImageBilateralFilter.h"
#import "GPUImageCrosshairGenerator.h"
#import "GPUImageToneCurveFilter.h"
#import "GPUImageNobleCornerDetectionFilter.h"
#import "GPUImageShiTomasiFeatureDetectionFilter.h"
#import "GPUImageErosionFilter.h"
#import "GPUImageRGBErosionFilter.h"
#import "GPUImageDilationFilter.h"
#import "GPUImageRGBDilationFilter.h"
#import "GPUImageOpeningFilter.h"
#import "GPUImageRGBOpeningFilter.h"
#import "GPUImageClosingFilter.h"
#import "GPUImageRGBClosingFilter.h"
#import "GPUImageColorPackingFilter.h"
#import "GPUImageSphereRefractionFilter.h"
#import "GPUImageMonochromeFilter.h"
#import "GPUImageOpacityFilter.h"
#import "GPUImageHighlightShadowFilter.h"
#import "GPUImageFalseColorFilter.h"
#import "GPUImageHSBFilter.h"
#import "GPUImageHueFilter.h"
#import "GPUImageGlassSphereFilter.h"
#import "GPUImageLookupFilter.h"
#import "GPUImageAmatorkaFilter.h"
#import "GPUImageMissEtikateFilter.h"
#import "GPUImageSoftEleganceFilter.h"
#import "GPUImageAddBlendFilter.h"
#import "GPUImageDivideBlendFilter.h"
#import "GPUImagePolkaDotFilter.h"
#import "GPUImageLocalBinaryPatternFilter.h"
#import "GPUImageColorLocalBinaryPatternFilter.h"
#import "GPUImageLanczosResamplingFilter.h"
#import "GPUImageAverageColor.h"
#import "GPUImageSolidColorGenerator.h"
#import "GPUImageLuminosity.h"
#import "GPUImageAverageLuminanceThresholdFilter.h"
#import "GPUImageWhiteBalanceFilter.h"
#import "GPUImageChromaKeyFilter.h"
#import "GPUImageLowPassFilter.h"
#import "GPUImageHighPassFilter.h"
#import "GPUImageMotionDetector.h"
#import "GPUImageHalftoneFilter.h"
#import "GPUImageThresholdedNonMaximumSuppressionFilter.h"
#import "GPUImageHoughTransformLineDetector.h"
#import "GPUImageParallelCoordinateLineTransformFilter.h"
#import "GPUImageThresholdSketchFilter.h"
#import "GPUImageLineGenerator.h"
#import "GPUImageLinearBurnBlendFilter.h"
#import "GPUImageGaussianBlurPositionFilter.h"
#import "GPUImagePixellatePositionFilter.h"
#import "GPUImageTwoInputCrossTextureSamplingFilter.h"
#import "GPUImagePoissonBlendFilter.h"
#import "GPUImageMotionBlurFilter.h"
#import "GPUImageZoomBlurFilter.h"
#import "GPUImageLaplacianFilter.h"
#import "GPUImageiOSBlurFilter.h"
#import "GPUImageLuminanceRangeFilter.h"
#import "GPUImageDirectionalNonMaximumSuppressionFilter.h"
#import "GPUImageDirectionalSobelEdgeDetectionFilter.h"
#import "GPUImageSingleComponentGaussianBlurFilter.h"
#import "GPUImageThreeInputFilter.h"
#import "GPUImageFourInputFilter.h"
#import "GPUImageWeakPixelInclusionFilter.h"
#import "GPUImageColorConversion.h"
#import "GPUImageColourFASTFeatureDetector.h"
#import "GPUImageColourFASTSamplingOperation.h"
@@ -1,18 +0,0 @@
#import "GPUImage3x3TextureSamplingFilter.h"
/** Runs a 3x3 convolution kernel against the image
*/
@interface GPUImage3x3ConvolutionFilter : GPUImage3x3TextureSamplingFilter
{
GLint convolutionMatrixUniform;
}
/** Convolution kernel to run against the image
The convolution kernel is a 3x3 matrix of values to apply to the pixel and its 8 surrounding pixels.
The matrix is specified in row-major order, with the top left pixel being one.one and the bottom right three.three
If the values in the matrix don't add up to 1.0, the image could be brightened or darkened.
*/
@property(readwrite, nonatomic) GPUMatrix3x3 convolutionKernel;
@end
@@ -1,18 +0,0 @@
#import "GPUImageFilter.h"
extern NSString *const kGPUImageNearbyTexelSamplingVertexShaderString;
@interface GPUImage3x3TextureSamplingFilter : GPUImageFilter
{
GLint texelWidthUniform, texelHeightUniform;
CGFloat texelWidth, texelHeight;
BOOL hasOverriddenImageSizeFactor;
}
// The texel width and height determines how far out to sample from this texel. By default, this is the normalized width of a pixel, but this can be overridden for different effects.
@property(readwrite, nonatomic) CGFloat texelWidth;
@property(readwrite, nonatomic) CGFloat texelHeight;
@end
@@ -1,9 +0,0 @@
#import "GPUImageFilterGroup.h"
@interface GPUImageAdaptiveThresholdFilter : GPUImageFilterGroup
/** A multiplier for the background averaging blur radius in pixels, with a default of 4
*/
@property(readwrite, nonatomic) CGFloat blurRadiusInPixels;
@end
@@ -1,5 +0,0 @@
#import "GPUImageTwoInputFilter.h"
@interface GPUImageAddBlendFilter : GPUImageTwoInputFilter
@end
@@ -1,11 +0,0 @@
#import "GPUImageTwoInputFilter.h"
@interface GPUImageAlphaBlendFilter : GPUImageTwoInputFilter
{
GLint mixUniform;
}
// Mix ranges from 0.0 (only image 1) to 1.0 (only image 2), with 1.0 as the normal level
@property(readwrite, nonatomic) CGFloat mix;
@end
@@ -1,17 +0,0 @@
#import "GPUImageFilterGroup.h"
@class GPUImagePicture;
/** A photo filter based on Photoshop action by Amatorka
http://amatorka.deviantart.com/art/Amatorka-Action-2-121069631
*/
// Note: If you want to use this effect you have to add lookup_amatorka.png
// from Resources folder to your application bundle.
@interface GPUImageAmatorkaFilter : GPUImageFilterGroup
{
GPUImagePicture *lookupImageSource;
}
@end
@@ -1,20 +0,0 @@
#import "GPUImageFilter.h"
extern NSString *const kGPUImageColorAveragingVertexShaderString;
@interface GPUImageAverageColor : GPUImageFilter
{
GLint texelWidthUniform, texelHeightUniform;
NSUInteger numberOfStages;
GLubyte *rawImagePixels;
CGSize finalStageSize;
}
// This block is called on the completion of color averaging for a frame
@property(nonatomic, copy) void(^colorAverageProcessingFinishedBlock)(CGFloat redComponent, CGFloat greenComponent, CGFloat blueComponent, CGFloat alphaComponent, CMTime frameTime);
- (void)extractAverageColorAtFrameTime:(CMTime)frameTime;
@end
@@ -1,8 +0,0 @@
#import "GPUImageFilterGroup.h"
@interface GPUImageAverageLuminanceThresholdFilter : GPUImageFilterGroup
// This is multiplied by the continually calculated average image luminosity to arrive at the final threshold. Default is 1.0.
@property(readwrite, nonatomic) CGFloat thresholdMultiplier;
@end
@@ -1,10 +0,0 @@
#import "GPUImageGaussianBlurFilter.h"
@interface GPUImageBilateralFilter : GPUImageGaussianBlurFilter
{
CGFloat firstDistanceNormalizationFactorUniform;
CGFloat secondDistanceNormalizationFactorUniform;
}
// A normalization factor for the distance between central color and sample color.
@property(nonatomic, readwrite) CGFloat distanceNormalizationFactor;
@end
@@ -1,7 +0,0 @@
#import "GPUImageGaussianBlurFilter.h"
/** A hardware-accelerated box blur of an image
*/
@interface GPUImageBoxBlurFilter : GPUImageGaussianBlurFilter
@end
@@ -1,11 +0,0 @@
#import "GPUImageFilter.h"
@interface GPUImageBrightnessFilter : GPUImageFilter
{
GLint brightnessUniform;
}
// Brightness ranges from -1.0 to 1.0, with 0.0 as the normal level
@property(readwrite, nonatomic) CGFloat brightness;
@end
-10
View File
@@ -1,10 +0,0 @@
#import "GPUImageFilter.h"
@interface GPUImageBuffer : GPUImageFilter
{
NSMutableArray *bufferedFramebuffers;
}
@property(readwrite, nonatomic) NSUInteger bufferSize;
@end
@@ -1,16 +0,0 @@
#import "GPUImageFilter.h"
/// Creates a bulge distortion on the image
@interface GPUImageBulgeDistortionFilter : GPUImageFilter
{
GLint aspectRatioUniform, radiusUniform, centerUniform, scaleUniform;
}
/// The center about which to apply the distortion, with a default of (0.5, 0.5)
@property(readwrite, nonatomic) CGPoint center;
/// The radius of the distortion, ranging from 0.0 to 1.0, with a default of 0.25
@property(readwrite, nonatomic) CGFloat radius;
/// The amount of distortion to apply, from -1.0 to 1.0, with a default of 0.5
@property(readwrite, nonatomic) CGFloat scale;
@end
@@ -1,5 +0,0 @@
#import "GPUImageFilter.h"
@interface GPUImageCGAColorspaceFilter : GPUImageFilter
@end
@@ -1,62 +0,0 @@
#import "GPUImageFilterGroup.h"
@class GPUImageGrayscaleFilter;
@class GPUImageSingleComponentGaussianBlurFilter;
@class GPUImageDirectionalSobelEdgeDetectionFilter;
@class GPUImageDirectionalNonMaximumSuppressionFilter;
@class GPUImageWeakPixelInclusionFilter;
/** This applies the edge detection process described by John Canny in
Canny, J., A Computational Approach To Edge Detection, IEEE Trans. Pattern Analysis and Machine Intelligence, 8(6):679698, 1986.
and implemented in OpenGL ES by
A. Ensor, S. Hall. GPU-based Image Analysis on Mobile Devices. Proceedings of Image and Vision Computing New Zealand 2011.
It starts with a conversion to luminance, followed by an accelerated 9-hit Gaussian blur. A Sobel operator is applied to obtain the overall
gradient strength in the blurred image, as well as the direction (in texture sampling steps) of the gradient. A non-maximum suppression filter
acts along the direction of the gradient, highlighting strong edges that pass the threshold and completely removing those that fail the lower
threshold. Finally, pixels from in-between these thresholds are either included in edges or rejected based on neighboring pixels.
*/
@interface GPUImageCannyEdgeDetectionFilter : GPUImageFilterGroup
{
GPUImageGrayscaleFilter *luminanceFilter;
GPUImageSingleComponentGaussianBlurFilter *blurFilter;
GPUImageDirectionalSobelEdgeDetectionFilter *edgeDetectionFilter;
GPUImageDirectionalNonMaximumSuppressionFilter *nonMaximumSuppressionFilter;
GPUImageWeakPixelInclusionFilter *weakPixelInclusionFilter;
}
/** The image width and height factors tweak the appearance of the edges.
These parameters affect the visibility of the detected edges
By default, they match the inverse of the filter size in pixels
*/
@property(readwrite, nonatomic) CGFloat texelWidth;
/** The image width and height factors tweak the appearance of the edges.
These parameters affect the visibility of the detected edges
By default, they match the inverse of the filter size in pixels
*/
@property(readwrite, nonatomic) CGFloat texelHeight;
/** The underlying blur radius for the Gaussian blur. Default is 2.0.
*/
@property (readwrite, nonatomic) CGFloat blurRadiusInPixels;
/** The underlying blur texel spacing multiplier. Default is 1.0.
*/
@property (readwrite, nonatomic) CGFloat blurTexelSpacingMultiplier;
/** Any edge with a gradient magnitude above this threshold will pass and show up in the final result.
*/
@property(readwrite, nonatomic) CGFloat upperThreshold;
/** Any edge with a gradient magnitude below this threshold will fail and be removed from the final result.
*/
@property(readwrite, nonatomic) CGFloat lowerThreshold;
@end
@@ -1,32 +0,0 @@
#import "GPUImageTwoInputFilter.h"
/** Selectively replaces a color in the first image with the second image
*/
@interface GPUImageChromaKeyBlendFilter : GPUImageTwoInputFilter
{
GLint colorToReplaceUniform, thresholdSensitivityUniform, smoothingUniform;
}
/** The threshold sensitivity controls how similar pixels need to be colored to be replaced
The default value is 0.3
*/
@property(readwrite, nonatomic) CGFloat thresholdSensitivity;
/** The degree of smoothing controls how gradually similar colors are replaced in the image
The default value is 0.1
*/
@property(readwrite, nonatomic) CGFloat smoothing;
/** The color to be replaced is specified using individual red, green, and blue components (normalized to 1.0).
The default is green: (0.0, 1.0, 0.0).
@param redComponent Red component of color to be replaced
@param greenComponent Green component of color to be replaced
@param blueComponent Blue component of color to be replaced
*/
- (void)setColorToReplaceRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
@end
@@ -1,30 +0,0 @@
#import "GPUImageFilter.h"
@interface GPUImageChromaKeyFilter : GPUImageFilter
{
GLint colorToReplaceUniform, thresholdSensitivityUniform, smoothingUniform;
}
/** The threshold sensitivity controls how similar pixels need to be colored to be replaced
The default value is 0.3
*/
@property(readwrite, nonatomic) CGFloat thresholdSensitivity;
/** The degree of smoothing controls how gradually similar colors are replaced in the image
The default value is 0.1
*/
@property(readwrite, nonatomic) CGFloat smoothing;
/** The color to be replaced is specified using individual red, green, and blue components (normalized to 1.0).
The default is green: (0.0, 1.0, 0.0).
@param redComponent Red component of color to be replaced
@param greenComponent Green component of color to be replaced
@param blueComponent Blue component of color to be replaced
*/
- (void)setColorToReplaceRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
@end
@@ -1,19 +0,0 @@
#import "GPUImageFilterGroup.h"
@class GPUImageErosionFilter;
@class GPUImageDilationFilter;
// A filter that first performs a dilation on the red channel of an image, followed by an erosion of the same radius.
// This helps to filter out smaller dark elements.
@interface GPUImageClosingFilter : GPUImageFilterGroup
{
GPUImageErosionFilter *erosionFilter;
GPUImageDilationFilter *dilationFilter;
}
@property(readwrite, nonatomic) CGFloat verticalTexelSpacing, horizontalTexelSpacing;
- (id)initWithRadius:(NSUInteger)radius;
@end
@@ -1,5 +0,0 @@
#import "GPUImageTwoInputFilter.h"
@interface GPUImageColorBlendFilter : GPUImageTwoInputFilter
@end
@@ -1,9 +0,0 @@
#import "GPUImageTwoInputFilter.h"
/** Applies a color burn blend of two images
*/
@interface GPUImageColorBurnBlendFilter : GPUImageTwoInputFilter
{
}
@end
@@ -1,12 +0,0 @@
#ifndef GPUImageColorConversion_h
#define GPUImageColorConversion_h
extern GLfloat *kColorConversion601;
extern GLfloat *kColorConversion601FullRange;
extern GLfloat *kColorConversion709;
extern NSString *const kGPUImageYUVVideoRangeConversionForRGFragmentShaderString;
extern NSString *const kGPUImageYUVFullRangeConversionForLAFragmentShaderString;
extern NSString *const kGPUImageYUVVideoRangeConversionForLAFragmentShaderString;
#endif /* GPUImageColorConversion_h */
@@ -1,9 +0,0 @@
#import "GPUImageTwoInputFilter.h"
/** Applies a color dodge blend of two images
*/
@interface GPUImageColorDodgeBlendFilter : GPUImageTwoInputFilter
{
}
@end
@@ -1,7 +0,0 @@
#import "GPUImageFilter.h"
@interface GPUImageColorInvertFilter : GPUImageFilter
{
}
@end
@@ -1,5 +0,0 @@
#import "GPUImage3x3TextureSamplingFilter.h"
@interface GPUImageColorLocalBinaryPatternFilter : GPUImage3x3TextureSamplingFilter
@end
@@ -1,19 +0,0 @@
#import "GPUImageFilter.h"
/** Transforms the colors of an image by applying a matrix to them
*/
@interface GPUImageColorMatrixFilter : GPUImageFilter
{
GLint colorMatrixUniform;
GLint intensityUniform;
}
/** A 4x4 matrix used to transform each color in an image
*/
@property(readwrite, nonatomic) GPUMatrix4x4 colorMatrix;
/** The degree to which the new transformed color replaces the original color for each pixel
*/
@property(readwrite, nonatomic) CGFloat intensity;
@end
@@ -1,10 +0,0 @@
#import "GPUImageFilter.h"
@interface GPUImageColorPackingFilter : GPUImageFilter
{
GLint texelWidthUniform, texelHeightUniform;
CGFloat texelWidth, texelHeight;
}
@end
@@ -1,21 +0,0 @@
#import "GPUImageFilterGroup.h"
// This generates image-wide feature descriptors using the ColourFAST process, as developed and described in
//
// A. Ensor and S. Hall. ColourFAST: GPU-based feature point detection and tracking on mobile devices. 28th International Conference of Image and Vision Computing, New Zealand, 2013, p. 124-129.
//
// Seth Hall, "GPU accelerated feature algorithms for mobile devices", PhD thesis, School of Computing and Mathematical Sciences, Auckland University of Technology 2014.
// http://aut.researchgateway.ac.nz/handle/10292/7991
@class GPUImageColourFASTSamplingOperation;
@class GPUImageBoxBlurFilter;
@interface GPUImageColourFASTFeatureDetector : GPUImageFilterGroup
{
GPUImageBoxBlurFilter *blurFilter;
GPUImageColourFASTSamplingOperation *colourFASTSamplingOperation;
}
// The blur radius of the underlying box blur. The default is 3.0.
@property (readwrite, nonatomic) CGFloat blurRadiusInPixels;
@end
@@ -1,22 +0,0 @@
#import "GPUImageTwoInputFilter.h"
// This is the feature extraction phase of the ColourFAST feature detector, as described in:
//
// A. Ensor and S. Hall. ColourFAST: GPU-based feature point detection and tracking on mobile devices. 28th International Conference of Image and Vision Computing, New Zealand, 2013, p. 124-129.
//
// Seth Hall, "GPU accelerated feature algorithms for mobile devices", PhD thesis, School of Computing and Mathematical Sciences, Auckland University of Technology 2014.
// http://aut.researchgateway.ac.nz/handle/10292/7991
@interface GPUImageColourFASTSamplingOperation : GPUImageTwoInputFilter
{
GLint texelWidthUniform, texelHeightUniform;
CGFloat texelWidth, texelHeight;
BOOL hasOverriddenImageSizeFactor;
}
// The texel width and height determines how far out to sample from this texel. By default, this is the normalized width of a pixel, but this can be overridden for different effects.
@property(readwrite, nonatomic) CGFloat texelWidth;
@property(readwrite, nonatomic) CGFloat texelHeight;
@end
-64
View File
@@ -1,64 +0,0 @@
#import "GLProgram.h"
#import "GPUImageFramebuffer.h"
#import "GPUImageFramebufferCache.h"
#define GPUImageRotationSwapsWidthAndHeight(rotation) ((rotation) == kGPUImageRotateLeft || (rotation) == kGPUImageRotateRight || (rotation) == kGPUImageRotateRightFlipVertical || (rotation) == kGPUImageRotateRightFlipHorizontal)
typedef NS_ENUM(NSUInteger, GPUImageRotationMode) {
kGPUImageNoRotation,
kGPUImageRotateLeft,
kGPUImageRotateRight,
kGPUImageFlipVertical,
kGPUImageFlipHorizonal,
kGPUImageRotateRightFlipVertical,
kGPUImageRotateRightFlipHorizontal,
kGPUImageRotate180
};
@interface GPUImageContext : NSObject
@property(readonly, nonatomic) dispatch_queue_t contextQueue;
@property(readwrite, retain, nonatomic) GLProgram *currentShaderProgram;
@property(readonly, retain, nonatomic) EAGLContext *context;
@property(readonly) CVOpenGLESTextureCacheRef coreVideoTextureCache;
@property(readonly) GPUImageFramebufferCache *framebufferCache;
+ (void *)contextKey;
+ (GPUImageContext *)sharedImageProcessingContext;
+ (dispatch_queue_t)sharedContextQueue;
+ (GPUImageFramebufferCache *)sharedFramebufferCache;
+ (void)useImageProcessingContext;
- (void)useAsCurrentContext;
+ (void)setActiveShaderProgram:(GLProgram *)shaderProgram;
- (void)setContextShaderProgram:(GLProgram *)shaderProgram;
+ (GLint)maximumTextureSizeForThisDevice;
+ (GLint)maximumTextureUnitsForThisDevice;
+ (GLint)maximumVaryingVectorsForThisDevice;
+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension;
+ (BOOL)deviceSupportsRedTextures;
+ (BOOL)deviceSupportsFramebufferReads;
+ (CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize;
- (void)presentBufferForDisplay;
- (GLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString;
- (void)useSharegroup:(EAGLSharegroup *)sharegroup;
// Manage fast texture upload
+ (BOOL)supportsFastTextureUpload;
@end
@protocol GPUImageInput <NSObject>
- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex;
- (NSInteger)nextAvailableTextureIndex;
- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;
- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;
- (CGSize)maximumOutputSize;
- (void)endProcessing;
- (BOOL)shouldIgnoreUpdatesToThisTarget;
- (BOOL)enabled;
- (BOOL)wantsMonochromeInput;
- (void)setCurrentlyReceivingMonochromeInput:(BOOL)newValue;
@end
@@ -1,14 +0,0 @@
#import "GPUImageFilter.h"
/** Adjusts the contrast of the image
*/
@interface GPUImageContrastFilter : GPUImageFilter
{
GLint contrastUniform;
}
/** Contrast ranges from 0.0 to 4.0 (max contrast), with 1.0 as the normal level
*/
@property(readwrite, nonatomic) CGFloat contrast;
@end
-14
View File
@@ -1,14 +0,0 @@
#import "GPUImageFilter.h"
@interface GPUImageCropFilter : GPUImageFilter
{
GLfloat cropTextureCoordinates[8];
}
// The crop region is the rectangle within the image to crop. It is normalized to a coordinate space from 0.0 to 1.0, with 0.0, 0.0 being the upper left corner of the image
@property(readwrite, nonatomic) CGRect cropRegion;
// Initialization and teardown
- (id)initWithCropRegion:(CGRect)newCropRegion;
@end
@@ -1,17 +0,0 @@
#import "GPUImageFilter.h"
@interface GPUImageCrosshairGenerator : GPUImageFilter
{
GLint crosshairWidthUniform, crosshairColorUniform;
}
// The width of the displayed crosshairs, in pixels. Currently this only works well for odd widths. The default is 5.
@property(readwrite, nonatomic) CGFloat crosshairWidth;
// The color of the crosshairs is specified using individual red, green, and blue components (normalized to 1.0). The default is green: (0.0, 1.0, 0.0).
- (void)setCrosshairColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
// Rendering
- (void)renderCrosshairsFromArray:(GLfloat *)crosshairCoordinates count:(NSUInteger)numberOfCrosshairs frameTime:(CMTime)frameTime;
@end
@@ -1,13 +0,0 @@
#import "GPUImageFilter.h"
@interface GPUImageCrosshatchFilter : GPUImageFilter
{
GLint crossHatchSpacingUniform, lineWidthUniform;
}
// The fractional width of the image to use as the spacing for the crosshatch. The default is 0.03.
@property(readwrite, nonatomic) CGFloat crossHatchSpacing;
// A relative width for the crosshatch lines. The default is 0.003.
@property(readwrite, nonatomic) CGFloat lineWidth;
@end
@@ -1,7 +0,0 @@
#import "GPUImageTwoInputFilter.h"
@interface GPUImageDarkenBlendFilter : GPUImageTwoInputFilter
{
}
@end
@@ -1,7 +0,0 @@
#import "GPUImageTwoInputFilter.h"
@interface GPUImageDifferenceBlendFilter : GPUImageTwoInputFilter
{
}
@end
@@ -1,16 +0,0 @@
#import "GPUImageTwoPassTextureSamplingFilter.h"
// For each pixel, this sets it to the maximum value of the red channel in a rectangular neighborhood extending out dilationRadius pixels from the center.
// This extends out bright features, and is most commonly used with black-and-white thresholded images.
extern NSString *const kGPUImageDilationRadiusOneVertexShaderString;
extern NSString *const kGPUImageDilationRadiusTwoVertexShaderString;
extern NSString *const kGPUImageDilationRadiusThreeVertexShaderString;
extern NSString *const kGPUImageDilationRadiusFourVertexShaderString;
@interface GPUImageDilationFilter : GPUImageTwoPassTextureSamplingFilter
// Acceptable values for dilationRadius, which sets the distance in pixels to sample out from the center, are 1, 2, 3, and 4.
- (id)initWithRadius:(NSUInteger)dilationRadius;
@end
@@ -1,19 +0,0 @@
#import "GPUImageFilter.h"
@interface GPUImageDirectionalNonMaximumSuppressionFilter : GPUImageFilter
{
GLint texelWidthUniform, texelHeightUniform;
GLint upperThresholdUniform, lowerThresholdUniform;
BOOL hasOverriddenImageSizeFactor;
}
// The texel width and height determines how far out to sample from this texel. By default, this is the normalized width of a pixel, but this can be overridden for different effects.
@property(readwrite, nonatomic) CGFloat texelWidth;
@property(readwrite, nonatomic) CGFloat texelHeight;
// These thresholds set cutoffs for the intensities that definitely get registered (upper threshold) and those that definitely don't (lower threshold)
@property(readwrite, nonatomic) CGFloat upperThreshold;
@property(readwrite, nonatomic) CGFloat lowerThreshold;
@end
@@ -1,5 +0,0 @@
#import "GPUImage3x3TextureSamplingFilter.h"
@interface GPUImageDirectionalSobelEdgeDetectionFilter : GPUImage3x3TextureSamplingFilter
@end
@@ -1,11 +0,0 @@
#import "GPUImageTwoInputFilter.h"
@interface GPUImageDissolveBlendFilter : GPUImageTwoInputFilter
{
GLint mixUniform;
}
// Mix ranges from 0.0 (only image 1) to 1.0 (only image 2), with 0.5 (half of either) as the normal level
@property(readwrite, nonatomic) CGFloat mix;
@end
@@ -1,5 +0,0 @@
#import "GPUImageTwoInputFilter.h"
@interface GPUImageDivideBlendFilter : GPUImageTwoInputFilter
@end
@@ -1,8 +0,0 @@
#import "GPUImage3x3ConvolutionFilter.h"
@interface GPUImageEmbossFilter : GPUImage3x3ConvolutionFilter
// The strength of the embossing, from 0.0 to 4.0, with 1.0 as the normal level
@property(readwrite, nonatomic) CGFloat intensity;
@end
@@ -1,11 +0,0 @@
#import "GPUImageTwoPassTextureSamplingFilter.h"
// For each pixel, this sets it to the minimum value of the red channel in a rectangular neighborhood extending out dilationRadius pixels from the center.
// This extends out dark features, and is most commonly used with black-and-white thresholded images.
@interface GPUImageErosionFilter : GPUImageTwoPassTextureSamplingFilter
// Acceptable values for erosionRadius, which sets the distance in pixels to sample out from the center, are 1, 2, 3, and 4.
- (id)initWithRadius:(NSUInteger)erosionRadius;
@end
@@ -1,7 +0,0 @@
#import "GPUImageTwoInputFilter.h"
@interface GPUImageExclusionBlendFilter : GPUImageTwoInputFilter
{
}
@end

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