JLChen
2020-11-12 4f0271c6055ad0532555f2cf4135998f07485dfb
2020-11-12 1.更新SDK
33个文件已添加
23个文件已修改
2778 ■■■■■ 已修改文件
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo.xcodeproj/project.pbxproj 656 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/AppDelegate.h 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/AppDelegate.m 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/Assets.xcassets/AppIcon.appiconset/Contents.json 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/Assets.xcassets/Contents.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/AudioSessionHelper.h 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/AudioSessionHelper.m 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/Base.lproj/LaunchScreen.storyboard 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/Base.lproj/Main.storyboard 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/ESVideo.h 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/ESVideo.m 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/Info.plist 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/SceneDelegate.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/SceneDelegate.m 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/ViewController.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/ViewController.mm 580 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/main.m 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemoTests/ESVideoPhoneSDKDemoTests.m 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemoTests/Info.plist 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemoUITests/ESVideoPhoneSDKDemoUITests.m 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemoUITests/Info.plist 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/ESVideoPhoneSDk 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/Headers/ESError.h 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/Headers/ESVideoPhone.h 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/Info.plist 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/_CodeSignature/CodeDirectory 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements-1 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/_CodeSignature/CodeResources 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/_CodeSignature/CodeSignature 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKZigbee/ESVideoPhoneSDKDemo/ZigBee/ESVideoMonitorViewController.m 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKZigbee/ESVideoPhoneSDKDemo/ZigBee/ESvideoVideoIntercomViewController.m 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/ESVideoPhoneSDk 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/Headers/ESVideoPhone.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/Info.plist 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/_CodeSignature/CodeDirectory 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements-1 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/_CodeSignature/CodeResources 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/_CodeSignature/CodeSignature 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/ESVideoPhoneSDKXamarin/ESVideoMonitorViewController.m 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/ESVideoPhoneSDKXamarin/ESvideoVideoIntercomViewController.m 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/ESVideoPhoneSDk 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/Headers/ESVideoPhone.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/Info.plist 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/_CodeSignature/CodeDirectory 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements-1 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/_CodeSignature/CodeResources 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/_CodeSignature/CodeSignature 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/ESVideoPhoneSDKXamarin/README.md 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/Shared.IOS.ESVideoPhoneSDK/Library/ESVideoPhoneSDk.a 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/Shared.IOS.ESVideoPhoneSDK/Library/libESVideoPhoneSDKXamarin.a 补丁 | 查看 | 原始文档 | blame | 历史
xamarin/Shared.IOS.ESVideoPhoneSDK/Properties/AssemblyInfo.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo.xcodeproj/project.pbxproj
New file
@@ -0,0 +1,656 @@
// !$*UTF8*$!
{
    archiveVersion = 1;
    classes = {
    };
    objectVersion = 50;
    objects = {
/* Begin PBXBuildFile section */
        B96CCD7A24A88EAD00FCCEBF /* ESVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = B96CCD7824A88EAD00FCCEBF /* ESVideo.m */; };
        C3385925233DAF06006940C3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C3385924233DAF06006940C3 /* AppDelegate.m */; };
        C3385928233DAF06006940C3 /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C3385927233DAF06006940C3 /* SceneDelegate.m */; };
        C338592B233DAF06006940C3 /* ViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = C338592A233DAF06006940C3 /* ViewController.mm */; };
        C338592E233DAF06006940C3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C338592C233DAF06006940C3 /* Main.storyboard */; };
        C3385930233DAF12006940C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C338592F233DAF12006940C3 /* Assets.xcassets */; };
        C3385933233DAF12006940C3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C3385931233DAF12006940C3 /* LaunchScreen.storyboard */; };
        C3385936233DAF12006940C3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C3385935233DAF12006940C3 /* main.m */; };
        C3385940233DAF12006940C3 /* ESVideoPhoneSDKDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C338593F233DAF12006940C3 /* ESVideoPhoneSDKDemoTests.m */; };
        C338594B233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = C338594A233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests.m */; };
        C345D08B233EEE520079C82C /* AudioSessionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = C345D08A233EEE520079C82C /* AudioSessionHelper.m */; };
        C3EBF9E823A72BCE00B62DDD /* ESVideoPhoneSDk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3EBF9E723A72BCD00B62DDD /* ESVideoPhoneSDk.framework */; };
        C3F59377233E0717009F09E5 /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = C3F59376233E0717009F09E5 /* libbz2.tbd */; };
        C3F59379233E0723009F09E5 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = C3F59378233E0723009F09E5 /* libz.tbd */; };
        C3F5937B233E0745009F09E5 /* libiconv.2.4.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = C3F5937A233E0744009F09E5 /* libiconv.2.4.0.tbd */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
        C338593C233DAF12006940C3 /* PBXContainerItemProxy */ = {
            isa = PBXContainerItemProxy;
            containerPortal = C3385918233DAF06006940C3 /* Project object */;
            proxyType = 1;
            remoteGlobalIDString = C338591F233DAF06006940C3;
            remoteInfo = ESVideoPhoneSDKDemo;
        };
        C3385947233DAF13006940C3 /* PBXContainerItemProxy */ = {
            isa = PBXContainerItemProxy;
            containerPortal = C3385918233DAF06006940C3 /* Project object */;
            proxyType = 1;
            remoteGlobalIDString = C338591F233DAF06006940C3;
            remoteInfo = ESVideoPhoneSDKDemo;
        };
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
        B924480E24934E5500F118F1 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
        B96CCD7824A88EAD00FCCEBF /* ESVideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESVideo.m; sourceTree = "<group>"; };
        B96CCD7924A88EAD00FCCEBF /* ESVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESVideo.h; sourceTree = "<group>"; };
        C3385920233DAF06006940C3 /* ESVideoPhoneSDKDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ESVideoPhoneSDKDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
        C3385923233DAF06006940C3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
        C3385924233DAF06006940C3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
        C3385926233DAF06006940C3 /* SceneDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SceneDelegate.h; sourceTree = "<group>"; };
        C3385927233DAF06006940C3 /* SceneDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SceneDelegate.m; sourceTree = "<group>"; };
        C3385929233DAF06006940C3 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
        C338592A233DAF06006940C3 /* ViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ViewController.mm; sourceTree = "<group>"; };
        C338592D233DAF06006940C3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
        C338592F233DAF12006940C3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
        C3385932233DAF12006940C3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
        C3385934233DAF12006940C3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
        C3385935233DAF12006940C3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
        C338593B233DAF12006940C3 /* ESVideoPhoneSDKDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ESVideoPhoneSDKDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
        C338593F233DAF12006940C3 /* ESVideoPhoneSDKDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ESVideoPhoneSDKDemoTests.m; sourceTree = "<group>"; };
        C3385941233DAF12006940C3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
        C3385946233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ESVideoPhoneSDKDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
        C338594A233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ESVideoPhoneSDKDemoUITests.m; sourceTree = "<group>"; };
        C338594C233DAF13006940C3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
        C345D089233EEE510079C82C /* AudioSessionHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioSessionHelper.h; sourceTree = "<group>"; };
        C345D08A233EEE520079C82C /* AudioSessionHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioSessionHelper.m; sourceTree = "<group>"; };
        C3EBF9E723A72BCD00B62DDD /* ESVideoPhoneSDk.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ESVideoPhoneSDk.framework; sourceTree = "<group>"; };
        C3F59376233E0717009F09E5 /* libbz2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = usr/lib/libbz2.tbd; sourceTree = SDKROOT; };
        C3F59378233E0723009F09E5 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
        C3F5937A233E0744009F09E5 /* libiconv.2.4.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.2.4.0.tbd; path = usr/lib/libiconv.2.4.0.tbd; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
        C338591D233DAF06006940C3 /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                C3EBF9E823A72BCE00B62DDD /* ESVideoPhoneSDk.framework in Frameworks */,
                C3F5937B233E0745009F09E5 /* libiconv.2.4.0.tbd in Frameworks */,
                C3F59379233E0723009F09E5 /* libz.tbd in Frameworks */,
                C3F59377233E0717009F09E5 /* libbz2.tbd in Frameworks */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        C3385938233DAF12006940C3 /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        C3385943233DAF13006940C3 /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
        C3385917233DAF06006940C3 = {
            isa = PBXGroup;
            children = (
                C3385922233DAF06006940C3 /* ESVideoPhoneSDKDemo */,
                C338593E233DAF12006940C3 /* ESVideoPhoneSDKDemoTests */,
                C3385949233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests */,
                C3385921233DAF06006940C3 /* Products */,
                C3E915CA233DFE4C00F77354 /* Frameworks */,
            );
            sourceTree = "<group>";
        };
        C3385921233DAF06006940C3 /* Products */ = {
            isa = PBXGroup;
            children = (
                C3385920233DAF06006940C3 /* ESVideoPhoneSDKDemo.app */,
                C338593B233DAF12006940C3 /* ESVideoPhoneSDKDemoTests.xctest */,
                C3385946233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests.xctest */,
            );
            name = Products;
            sourceTree = "<group>";
        };
        C3385922233DAF06006940C3 /* ESVideoPhoneSDKDemo */ = {
            isa = PBXGroup;
            children = (
                B96CCD7924A88EAD00FCCEBF /* ESVideo.h */,
                B96CCD7824A88EAD00FCCEBF /* ESVideo.m */,
                C3385923233DAF06006940C3 /* AppDelegate.h */,
                C3385924233DAF06006940C3 /* AppDelegate.m */,
                C3385926233DAF06006940C3 /* SceneDelegate.h */,
                C3385927233DAF06006940C3 /* SceneDelegate.m */,
                C3385929233DAF06006940C3 /* ViewController.h */,
                C338592A233DAF06006940C3 /* ViewController.mm */,
                C345D089233EEE510079C82C /* AudioSessionHelper.h */,
                C345D08A233EEE520079C82C /* AudioSessionHelper.m */,
                C338592C233DAF06006940C3 /* Main.storyboard */,
                C338592F233DAF12006940C3 /* Assets.xcassets */,
                C3385931233DAF12006940C3 /* LaunchScreen.storyboard */,
                C3385934233DAF12006940C3 /* Info.plist */,
                C3385935233DAF12006940C3 /* main.m */,
            );
            path = ESVideoPhoneSDKDemo;
            sourceTree = "<group>";
        };
        C338593E233DAF12006940C3 /* ESVideoPhoneSDKDemoTests */ = {
            isa = PBXGroup;
            children = (
                C338593F233DAF12006940C3 /* ESVideoPhoneSDKDemoTests.m */,
                C3385941233DAF12006940C3 /* Info.plist */,
            );
            path = ESVideoPhoneSDKDemoTests;
            sourceTree = "<group>";
        };
        C3385949233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests */ = {
            isa = PBXGroup;
            children = (
                C338594A233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests.m */,
                C338594C233DAF13006940C3 /* Info.plist */,
            );
            path = ESVideoPhoneSDKDemoUITests;
            sourceTree = "<group>";
        };
        C3E915CA233DFE4C00F77354 /* Frameworks */ = {
            isa = PBXGroup;
            children = (
                B924480E24934E5500F118F1 /* AudioToolbox.framework */,
                C3EBF9E723A72BCD00B62DDD /* ESVideoPhoneSDk.framework */,
                C3F5937A233E0744009F09E5 /* libiconv.2.4.0.tbd */,
                C3F59378233E0723009F09E5 /* libz.tbd */,
                C3F59376233E0717009F09E5 /* libbz2.tbd */,
            );
            name = Frameworks;
            sourceTree = "<group>";
        };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
        C338591F233DAF06006940C3 /* ESVideoPhoneSDKDemo */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = C338594F233DAF13006940C3 /* Build configuration list for PBXNativeTarget "ESVideoPhoneSDKDemo" */;
            buildPhases = (
                C338591C233DAF06006940C3 /* Sources */,
                C338591D233DAF06006940C3 /* Frameworks */,
                C338591E233DAF06006940C3 /* Resources */,
            );
            buildRules = (
            );
            dependencies = (
            );
            name = ESVideoPhoneSDKDemo;
            productName = ESVideoPhoneSDKDemo;
            productReference = C3385920233DAF06006940C3 /* ESVideoPhoneSDKDemo.app */;
            productType = "com.apple.product-type.application";
        };
        C338593A233DAF12006940C3 /* ESVideoPhoneSDKDemoTests */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = C3385952233DAF13006940C3 /* Build configuration list for PBXNativeTarget "ESVideoPhoneSDKDemoTests" */;
            buildPhases = (
                C3385937233DAF12006940C3 /* Sources */,
                C3385938233DAF12006940C3 /* Frameworks */,
                C3385939233DAF12006940C3 /* Resources */,
            );
            buildRules = (
            );
            dependencies = (
                C338593D233DAF12006940C3 /* PBXTargetDependency */,
            );
            name = ESVideoPhoneSDKDemoTests;
            productName = ESVideoPhoneSDKDemoTests;
            productReference = C338593B233DAF12006940C3 /* ESVideoPhoneSDKDemoTests.xctest */;
            productType = "com.apple.product-type.bundle.unit-test";
        };
        C3385945233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = C3385955233DAF13006940C3 /* Build configuration list for PBXNativeTarget "ESVideoPhoneSDKDemoUITests" */;
            buildPhases = (
                C3385942233DAF13006940C3 /* Sources */,
                C3385943233DAF13006940C3 /* Frameworks */,
                C3385944233DAF13006940C3 /* Resources */,
            );
            buildRules = (
            );
            dependencies = (
                C3385948233DAF13006940C3 /* PBXTargetDependency */,
            );
            name = ESVideoPhoneSDKDemoUITests;
            productName = ESVideoPhoneSDKDemoUITests;
            productReference = C3385946233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests.xctest */;
            productType = "com.apple.product-type.bundle.ui-testing";
        };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
        C3385918233DAF06006940C3 /* Project object */ = {
            isa = PBXProject;
            attributes = {
                LastUpgradeCheck = 1100;
                ORGANIZATIONNAME = eTouchSky;
                TargetAttributes = {
                    C338591F233DAF06006940C3 = {
                        CreatedOnToolsVersion = 11.0;
                    };
                    C338593A233DAF12006940C3 = {
                        CreatedOnToolsVersion = 11.0;
                        TestTargetID = C338591F233DAF06006940C3;
                    };
                    C3385945233DAF13006940C3 = {
                        CreatedOnToolsVersion = 11.0;
                        TestTargetID = C338591F233DAF06006940C3;
                    };
                };
            };
            buildConfigurationList = C338591B233DAF06006940C3 /* Build configuration list for PBXProject "ESVideoPhoneSDKDemo" */;
            compatibilityVersion = "Xcode 9.3";
            developmentRegion = en;
            hasScannedForEncodings = 0;
            knownRegions = (
                en,
                Base,
            );
            mainGroup = C3385917233DAF06006940C3;
            productRefGroup = C3385921233DAF06006940C3 /* Products */;
            projectDirPath = "";
            projectRoot = "";
            targets = (
                C338591F233DAF06006940C3 /* ESVideoPhoneSDKDemo */,
                C338593A233DAF12006940C3 /* ESVideoPhoneSDKDemoTests */,
                C3385945233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests */,
            );
        };
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
        C338591E233DAF06006940C3 /* Resources */ = {
            isa = PBXResourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                C3385933233DAF12006940C3 /* LaunchScreen.storyboard in Resources */,
                C3385930233DAF12006940C3 /* Assets.xcassets in Resources */,
                C338592E233DAF06006940C3 /* Main.storyboard in Resources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        C3385939233DAF12006940C3 /* Resources */ = {
            isa = PBXResourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        C3385944233DAF13006940C3 /* Resources */ = {
            isa = PBXResourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
        C338591C233DAF06006940C3 /* Sources */ = {
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                C338592B233DAF06006940C3 /* ViewController.mm in Sources */,
                B96CCD7A24A88EAD00FCCEBF /* ESVideo.m in Sources */,
                C3385925233DAF06006940C3 /* AppDelegate.m in Sources */,
                C345D08B233EEE520079C82C /* AudioSessionHelper.m in Sources */,
                C3385936233DAF12006940C3 /* main.m in Sources */,
                C3385928233DAF06006940C3 /* SceneDelegate.m in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        C3385937233DAF12006940C3 /* Sources */ = {
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                C3385940233DAF12006940C3 /* ESVideoPhoneSDKDemoTests.m in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        C3385942233DAF13006940C3 /* Sources */ = {
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                C338594B233DAF13006940C3 /* ESVideoPhoneSDKDemoUITests.m in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
        C338593D233DAF12006940C3 /* PBXTargetDependency */ = {
            isa = PBXTargetDependency;
            target = C338591F233DAF06006940C3 /* ESVideoPhoneSDKDemo */;
            targetProxy = C338593C233DAF12006940C3 /* PBXContainerItemProxy */;
        };
        C3385948233DAF13006940C3 /* PBXTargetDependency */ = {
            isa = PBXTargetDependency;
            target = C338591F233DAF06006940C3 /* ESVideoPhoneSDKDemo */;
            targetProxy = C3385947233DAF13006940C3 /* PBXContainerItemProxy */;
        };
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
        C338592C233DAF06006940C3 /* Main.storyboard */ = {
            isa = PBXVariantGroup;
            children = (
                C338592D233DAF06006940C3 /* Base */,
            );
            name = Main.storyboard;
            sourceTree = "<group>";
        };
        C3385931233DAF12006940C3 /* LaunchScreen.storyboard */ = {
            isa = PBXVariantGroup;
            children = (
                C3385932233DAF12006940C3 /* Base */,
            );
            name = LaunchScreen.storyboard;
            sourceTree = "<group>";
        };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
        C338594D233DAF13006940C3 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ALWAYS_SEARCH_USER_PATHS = NO;
                CLANG_ANALYZER_NONNULL = YES;
                CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
                CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                CLANG_CXX_LIBRARY = "libc++";
                CLANG_ENABLE_MODULES = YES;
                CLANG_ENABLE_OBJC_ARC = YES;
                CLANG_ENABLE_OBJC_WEAK = YES;
                CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_COMMA = YES;
                CLANG_WARN_CONSTANT_CONVERSION = YES;
                CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
                CLANG_WARN_EMPTY_BODY = YES;
                CLANG_WARN_ENUM_CONVERSION = YES;
                CLANG_WARN_INFINITE_RECURSION = YES;
                CLANG_WARN_INT_CONVERSION = YES;
                CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
                CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
                CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
                CLANG_WARN_STRICT_PROTOTYPES = YES;
                CLANG_WARN_SUSPICIOUS_MOVE = YES;
                CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                COPY_PHASE_STRIP = NO;
                DEBUG_INFORMATION_FORMAT = dwarf;
                ENABLE_BITCODE = NO;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                ENABLE_TESTABILITY = YES;
                GCC_C_LANGUAGE_STANDARD = gnu11;
                GCC_DYNAMIC_NO_PIC = NO;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_OPTIMIZATION_LEVEL = 0;
                GCC_PREPROCESSOR_DEFINITIONS = (
                    "DEBUG=1",
                    "$(inherited)",
                );
                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                GCC_WARN_UNUSED_FUNCTION = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                IPHONEOS_DEPLOYMENT_TARGET = 10.0;
                MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
                MTL_FAST_MATH = YES;
                ONLY_ACTIVE_ARCH = YES;
                OTHER_LDFLAGS = "-Wl,-all_load";
                SDKROOT = iphoneos;
                VALID_ARCHS = "arm64 arm64e";
            };
            name = Debug;
        };
        C338594E233DAF13006940C3 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ALWAYS_SEARCH_USER_PATHS = NO;
                CLANG_ANALYZER_NONNULL = YES;
                CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
                CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                CLANG_CXX_LIBRARY = "libc++";
                CLANG_ENABLE_MODULES = YES;
                CLANG_ENABLE_OBJC_ARC = YES;
                CLANG_ENABLE_OBJC_WEAK = YES;
                CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_COMMA = YES;
                CLANG_WARN_CONSTANT_CONVERSION = YES;
                CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
                CLANG_WARN_EMPTY_BODY = YES;
                CLANG_WARN_ENUM_CONVERSION = YES;
                CLANG_WARN_INFINITE_RECURSION = YES;
                CLANG_WARN_INT_CONVERSION = YES;
                CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
                CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
                CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
                CLANG_WARN_STRICT_PROTOTYPES = YES;
                CLANG_WARN_SUSPICIOUS_MOVE = YES;
                CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                COPY_PHASE_STRIP = NO;
                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                ENABLE_BITCODE = NO;
                ENABLE_NS_ASSERTIONS = NO;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                GCC_C_LANGUAGE_STANDARD = gnu11;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                GCC_WARN_UNUSED_FUNCTION = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                IPHONEOS_DEPLOYMENT_TARGET = 10.0;
                MTL_ENABLE_DEBUG_INFO = NO;
                MTL_FAST_MATH = YES;
                OTHER_LDFLAGS = "-Wl,-all_load";
                SDKROOT = iphoneos;
                VALIDATE_PRODUCT = YES;
                VALID_ARCHS = "arm64 arm64e";
            };
            name = Release;
        };
        C3385950233DAF13006940C3 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
                CODE_SIGN_IDENTITY = "iPhone Developer";
                CODE_SIGN_STYLE = Manual;
                DEVELOPMENT_TEAM = BVTA78PRYA;
                FRAMEWORK_SEARCH_PATHS = (
                    "$(inherited)",
                    "$(PROJECT_DIR)/ESVideoPhoneSDKDemo",
                    "$(PROJECT_DIR)",
                );
                INFOPLIST_FILE = ESVideoPhoneSDKDemo/Info.plist;
                IPHONEOS_DEPLOYMENT_TARGET = 8.0;
                LD_RUNPATH_SEARCH_PATHS = (
                    "$(inherited)",
                    "@executable_path/Frameworks",
                );
                LIBRARY_SEARCH_PATHS = "$(inherited)";
                MARKETING_VERSION = 1.2;
                OTHER_LDFLAGS = "-Wl,-all_load";
                PRODUCT_BUNDLE_IDENTIFIER = com.hdl.ESVideoPhoneSDKDemo2;
                PRODUCT_NAME = "$(TARGET_NAME)";
                PROVISIONING_PROFILE_SPECIFIER = Test;
                TARGETED_DEVICE_FAMILY = 1;
            };
            name = Debug;
        };
        C3385951233DAF13006940C3 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
                CODE_SIGN_IDENTITY = "iPhone Developer";
                CODE_SIGN_STYLE = Manual;
                DEVELOPMENT_TEAM = BVTA78PRYA;
                FRAMEWORK_SEARCH_PATHS = (
                    "$(inherited)",
                    "$(PROJECT_DIR)/ESVideoPhoneSDKDemo",
                    "$(PROJECT_DIR)",
                );
                INFOPLIST_FILE = ESVideoPhoneSDKDemo/Info.plist;
                IPHONEOS_DEPLOYMENT_TARGET = 8.0;
                LD_RUNPATH_SEARCH_PATHS = (
                    "$(inherited)",
                    "@executable_path/Frameworks",
                );
                LIBRARY_SEARCH_PATHS = "$(inherited)";
                MARKETING_VERSION = 1.2;
                OTHER_LDFLAGS = "-Wl,-all_load";
                PRODUCT_BUNDLE_IDENTIFIER = com.hdl.ESVideoPhoneSDKDemo2;
                PRODUCT_NAME = "$(TARGET_NAME)";
                PROVISIONING_PROFILE_SPECIFIER = Test;
                TARGETED_DEVICE_FAMILY = 1;
            };
            name = Release;
        };
        C3385953233DAF13006940C3 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                BUNDLE_LOADER = "$(TEST_HOST)";
                CODE_SIGN_STYLE = Automatic;
                DEVELOPMENT_TEAM = 754E2P9CSA;
                INFOPLIST_FILE = ESVideoPhoneSDKDemoTests/Info.plist;
                IPHONEOS_DEPLOYMENT_TARGET = 13.0;
                LD_RUNPATH_SEARCH_PATHS = (
                    "$(inherited)",
                    "@executable_path/Frameworks",
                    "@loader_path/Frameworks",
                );
                PRODUCT_BUNDLE_IDENTIFIER = eTouchSky.ESVideoPhoneSDKDemoTests;
                PRODUCT_NAME = "$(TARGET_NAME)";
                TARGETED_DEVICE_FAMILY = "1,2";
                TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ESVideoPhoneSDKDemo.app/ESVideoPhoneSDKDemo";
            };
            name = Debug;
        };
        C3385954233DAF13006940C3 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                BUNDLE_LOADER = "$(TEST_HOST)";
                CODE_SIGN_STYLE = Automatic;
                DEVELOPMENT_TEAM = 754E2P9CSA;
                INFOPLIST_FILE = ESVideoPhoneSDKDemoTests/Info.plist;
                IPHONEOS_DEPLOYMENT_TARGET = 13.0;
                LD_RUNPATH_SEARCH_PATHS = (
                    "$(inherited)",
                    "@executable_path/Frameworks",
                    "@loader_path/Frameworks",
                );
                PRODUCT_BUNDLE_IDENTIFIER = eTouchSky.ESVideoPhoneSDKDemoTests;
                PRODUCT_NAME = "$(TARGET_NAME)";
                TARGETED_DEVICE_FAMILY = "1,2";
                TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ESVideoPhoneSDKDemo.app/ESVideoPhoneSDKDemo";
            };
            name = Release;
        };
        C3385956233DAF13006940C3 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                CODE_SIGN_STYLE = Automatic;
                DEVELOPMENT_TEAM = 754E2P9CSA;
                INFOPLIST_FILE = ESVideoPhoneSDKDemoUITests/Info.plist;
                LD_RUNPATH_SEARCH_PATHS = (
                    "$(inherited)",
                    "@executable_path/Frameworks",
                    "@loader_path/Frameworks",
                );
                PRODUCT_BUNDLE_IDENTIFIER = eTouchSky.ESVideoPhoneSDKDemoUITests;
                PRODUCT_NAME = "$(TARGET_NAME)";
                TARGETED_DEVICE_FAMILY = "1,2";
                TEST_TARGET_NAME = ESVideoPhoneSDKDemo;
            };
            name = Debug;
        };
        C3385957233DAF13006940C3 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                CODE_SIGN_STYLE = Automatic;
                DEVELOPMENT_TEAM = 754E2P9CSA;
                INFOPLIST_FILE = ESVideoPhoneSDKDemoUITests/Info.plist;
                LD_RUNPATH_SEARCH_PATHS = (
                    "$(inherited)",
                    "@executable_path/Frameworks",
                    "@loader_path/Frameworks",
                );
                PRODUCT_BUNDLE_IDENTIFIER = eTouchSky.ESVideoPhoneSDKDemoUITests;
                PRODUCT_NAME = "$(TARGET_NAME)";
                TARGETED_DEVICE_FAMILY = "1,2";
                TEST_TARGET_NAME = ESVideoPhoneSDKDemo;
            };
            name = Release;
        };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
        C338591B233DAF06006940C3 /* Build configuration list for PBXProject "ESVideoPhoneSDKDemo" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
                C338594D233DAF13006940C3 /* Debug */,
                C338594E233DAF13006940C3 /* Release */,
            );
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        C338594F233DAF13006940C3 /* Build configuration list for PBXNativeTarget "ESVideoPhoneSDKDemo" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
                C3385950233DAF13006940C3 /* Debug */,
                C3385951233DAF13006940C3 /* Release */,
            );
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        C3385952233DAF13006940C3 /* Build configuration list for PBXNativeTarget "ESVideoPhoneSDKDemoTests" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
                C3385953233DAF13006940C3 /* Debug */,
                C3385954233DAF13006940C3 /* Release */,
            );
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        C3385955233DAF13006940C3 /* Build configuration list for PBXNativeTarget "ESVideoPhoneSDKDemoUITests" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
                C3385956233DAF13006940C3 /* Debug */,
                C3385957233DAF13006940C3 /* Release */,
            );
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
/* End XCConfigurationList section */
    };
    rootObject = C3385918233DAF06006940C3 /* Project object */;
}
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "self:ESVideoPhoneSDKDemo.xcodeproj">
   </FileRef>
</Workspace>
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
New file
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>IDEDidComputeMac32BitWarning</key>
    <true/>
</dict>
</plist>
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/AppDelegate.h
New file
@@ -0,0 +1,15 @@
//
//  AppDelegate.h
//  ESVideoPhoneSDKDemo
//
//  Created by eTouchSky on 2019/9/27.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/AppDelegate.m
New file
@@ -0,0 +1,42 @@
//
//  AppDelegate.m
//  ESVideoPhoneSDKDemo
//
//  Created by eTouchSky on 2019/9/27.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}
#pragma mark - UISceneSession lifecycle
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/Assets.xcassets/AppIcon.appiconset/Contents.json
New file
@@ -0,0 +1,98 @@
{
  "images" : [
    {
      "idiom" : "iphone",
      "size" : "20x20",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "20x20",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "3x"
    },
    {
      "idiom" : "ipad",
      "size" : "20x20",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "20x20",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "29x29",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "40x40",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "76x76",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "76x76",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "83.5x83.5",
      "scale" : "2x"
    },
    {
      "idiom" : "ios-marketing",
      "size" : "1024x1024",
      "scale" : "1x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/Assets.xcassets/Contents.json
New file
@@ -0,0 +1,6 @@
{
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/AudioSessionHelper.h
New file
@@ -0,0 +1,19 @@
//
//  AudioSessionHelper.h
//  VideoPhone
//
//  Created by eTouchSky on 2019/5/30.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface AudioSessionHelper : NSObject
- (void)setAudioSession;
-(NSString *)speaker:(BOOL)isSpeaking;
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/AudioSessionHelper.m
New file
@@ -0,0 +1,124 @@
//
//  AudioSessionHelper.m
//  VideoPhone
//
//  Created by eTouchSky on 2019/5/30.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
#import "AudioSessionHelper.h"
#import <AVFoundation/AVFoundation.h>
@interface AudioSessionHelper()
@property (nonatomic,assign) BOOL                  speaking;
@end
@implementation AudioSessionHelper
#pragma mark -- AVAudioSession的设置
-(void)setAudioSession{
    NSError *error = nil;
    //免提播放 有回声: 网络引起回音(两个手机隔太近就会很大)。 手机本身的设计有问题(录播),关闭降噪功能(关闭后基本没有了)
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
    if (error) {
        NSLog(@"AVAudioSessionCategoryPlayAndRecord error:%@", error);
    }else{
        NSLog(@"听筒播放");
    }
    [[AVAudioSession sharedInstance] setActive:YES withOptions:kAudioSessionSetActiveFlag_NotifyOthersOnDeactivation error:&error];
    [[AVAudioSession sharedInstance] setPreferredIOBufferDuration:0.05 error:&error];
    if (error) {
        NSLog(@"AVAudioSessionSetPreferredIOBufferDuration error:%@", error);
    }
    /**< 码率设置不正确会导致播放出来的声音变尖或变平,有一点拖音或者最后一点音少了,8000的采样率设置16000的码率很好>*/
    [[AVAudioSession sharedInstance] setPreferredSampleRate:16000 error:&error];
    if (error) {
        NSLog(@"setPreferredSampleRate error:%@", error);
    }
}
//必须先setActive:NO  再设置option  再setActive:YES, 否则有些系统,有些畸形,在听筒模式下不能采集
//这里打断点测试可能会报错:p2p终端,解码器终端。
-(NSString *)speaker:(BOOL)isSpeaking{
    NSError *error = nil;
    [[AVAudioSession sharedInstance] setActive:NO error:&error];
    if (error) {
        NSLog(@"setActive:NO error:%@", error);
    }
    if (isSpeaking == NO) {
        //听筒播放 效果很好
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
        if (error) {
            NSLog(@"AVAudioSessionCategoryPlayAndRecord error:%@", error);
            return nil;
        }else{
            NSLog(@"听筒播放");
             [[AVAudioSession sharedInstance] setActive:YES withOptions:kAudioSessionSetActiveFlag_NotifyOthersOnDeactivation error:&error];
            if (error) {
                NSLog(@"setActive:YES error:%@", error);
            }
           [self LogAudioSessionInfo];
            return @"免提";
        }
    }else{
        //免提播放 有回声: 网络引起回音(两个手机隔太近就会很大)。 手机本身的设计有问题(录播),关闭降噪功能(关闭后基本没有了)
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&error];
        if (error) {
            NSLog(@"AVAudioSessionCategoryOptionDefaultToSpeaker error:%@", error);
            return nil;
        }else{
            NSLog(@"免提播放");
             [[AVAudioSession sharedInstance] setActive:YES withOptions:kAudioSessionSetActiveFlag_NotifyOthersOnDeactivation error:&error];
            if (error) {
                NSLog(@"setActive:YES error:%@", error);
            }
            //[self LogAudioSessionInfo];
            return @"听筒";
        }
    }
}
-(void)LogAudioSessionInfo{
    AVAudioSessionCategory category = [[AVAudioSession sharedInstance] category];
    AVAudioSessionCategoryOptions option = [[AVAudioSession sharedInstance] categoryOptions];
    NSArray* inputArray = [[AVAudioSession sharedInstance] availableInputs];
    NSArray* outputArray = [AVAudioSession sharedInstance].currentRoute.outputs;
    NSLog(@"%@", category);
    NSLog(@"%lu", (unsigned long)option);
    NSLog(@"%@", inputArray);
    NSLog(@"%@", outputArray);
}
/*
-(void)changeMicToHeadset{
    NSArray* inputArray = [[AVAudioSession sharedInstance] availableInputs];
    for (AVAudioSessionPortDescription* desc in inputArray) {
        if ([desc.portType isEqualToString:AVAudioSessionPortHeadsetMic]) {
            NSError* error;
            [[AVAudioSession sharedInstance] setPreferredInput:desc error:&error];
        }
    }
}
-(void)changeMicToBuiltIn{
    NSArray* inputArray = [[AVAudioSession sharedInstance] availableInputs];
    for (AVAudioSessionPortDescription* desc in inputArray) {
        if ([desc.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {
            NSError* error;
            [[AVAudioSession sharedInstance] setPreferredInput:desc error:&error];
        }
    }
}
*/
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/Base.lproj/LaunchScreen.storyboard
New file
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
    <device id="retina4_7" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="EHf-IW-A2E">
            <objects>
                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="oCk-sZ-pj6"/>
                        <viewControllerLayoutGuide type="bottom" id="850-qB-SUI"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Ze5-6b-2t3">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="53" y="375"/>
        </scene>
    </scenes>
</document>
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/Base.lproj/Main.storyboard
New file
@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="Otu-wo-FUs">
    <device id="retina6_1" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15510"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="Wzv-3T-9rg"/>
                        <viewControllerLayoutGuide type="bottom" id="COG-Nv-9Ga"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0" width="414" height="842"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vJi-oZ-LSc">
                                <rect key="frame" x="40" y="738" width="60" height="30"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="30" id="2Pc-3k-dUO"/>
                                    <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="cuo-Ky-5Dv"/>
                                </constraints>
                                <state key="normal" title="听筒"/>
                                <connections>
                                    <action selector="speaker:" destination="BYZ-38-t0r" eventType="touchUpInside" id="W7q-iX-a2t"/>
                                </connections>
                            </button>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jPl-Vg-g3C">
                                <rect key="frame" x="120" y="738" width="60" height="30"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="30" id="3O0-xV-2Xd"/>
                                    <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="XJm-Mv-gZS"/>
                                </constraints>
                                <state key="normal" title="开门"/>
                                <connections>
                                    <action selector="openDoor:" destination="BYZ-38-t0r" eventType="touchUpInside" id="QiK-iu-wu4"/>
                                </connections>
                            </button>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mdf-GC-mIQ">
                                <rect key="frame" x="200" y="738" width="60" height="30"/>
                                <constraints>
                                    <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="Sm2-me-6Rj"/>
                                    <constraint firstAttribute="height" constant="30" id="ln6-ba-aYV"/>
                                </constraints>
                                <state key="normal" title="截图"/>
                                <connections>
                                    <action selector="onSnap:" destination="BYZ-38-t0r" eventType="touchUpInside" id="dvX-n1-L3W"/>
                                </connections>
                            </button>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="koH-BL-KZA">
                                <rect key="frame" x="40" y="688" width="60" height="30"/>
                                <constraints>
                                    <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="JB7-ql-xzA"/>
                                </constraints>
                                <state key="normal" title="反呼"/>
                                <connections>
                                    <action selector="onReverseCall:" destination="BYZ-38-t0r" eventType="touchUpInside" id="R22-bQ-kpF"/>
                                </connections>
                            </button>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WJI-4Z-VeA">
                                <rect key="frame" x="120" y="688" width="60" height="30"/>
                                <constraints>
                                    <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="csc-sy-eEr"/>
                                    <constraint firstAttribute="height" constant="30" id="vza-fv-qdl"/>
                                </constraints>
                                <state key="normal" title="挂断"/>
                                <connections>
                                    <action selector="onHangup:" destination="BYZ-38-t0r" eventType="touchUpInside" id="mUK-dK-0eT"/>
                                </connections>
                            </button>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LcR-MR-y9c">
                                <rect key="frame" x="200" y="688" width="60" height="30"/>
                                <constraints>
                                    <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="7N3-EE-cFS"/>
                                    <constraint firstAttribute="height" constant="30" id="go1-vo-L2j"/>
                                </constraints>
                                <state key="normal" title="监控"/>
                                <connections>
                                    <action selector="onMonitor:" destination="BYZ-38-t0r" eventType="touchUpInside" id="RcS-6u-LBX"/>
                                </connections>
                            </button>
                            <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Vfn-FR-1Ub">
                                <rect key="frame" x="102" y="0.0" width="282" height="30"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="30" id="JFw-sW-vcm"/>
                                </constraints>
                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                <textInputTraits key="textInputTraits" returnKeyType="done"/>
                            </textField>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="门口机" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E2O-cv-ota">
                                <rect key="frame" x="40" y="0.0" width="52" height="30"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="30" id="VRD-h4-kIL"/>
                                </constraints>
                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Uhq-CJ-D5N">
                                <rect key="frame" x="288" y="738" width="31" height="30"/>
                                <state key="normal" title="返回"/>
                                <connections>
                                    <action selector="back:" destination="BYZ-38-t0r" eventType="touchUpInside" id="Cky-im-DhB"/>
                                </connections>
                            </button>
                        </subviews>
                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                        <constraints>
                            <constraint firstItem="Vfn-FR-1Ub" firstAttribute="leading" secondItem="E2O-cv-ota" secondAttribute="trailing" constant="10" id="0RX-sz-eS9"/>
                            <constraint firstItem="E2O-cv-ota" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="20" id="17C-bm-Akt"/>
                            <constraint firstItem="E2O-cv-ota" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="20" id="1qo-7b-cDh"/>
                            <constraint firstAttribute="trailing" secondItem="LcR-MR-y9c" secondAttribute="trailing" constant="154" id="Ac2-pr-p5A"/>
                            <constraint firstItem="vJi-oZ-LSc" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="20" id="AeG-dA-Pth"/>
                            <constraint firstItem="Uhq-CJ-D5N" firstAttribute="leading" secondItem="mdf-GC-mIQ" secondAttribute="trailing" constant="28" id="BCG-1O-c7I"/>
                            <constraint firstItem="vJi-oZ-LSc" firstAttribute="top" secondItem="koH-BL-KZA" secondAttribute="bottom" constant="20" id="Bgv-gv-AxZ"/>
                            <constraint firstItem="jPl-Vg-g3C" firstAttribute="leading" secondItem="vJi-oZ-LSc" secondAttribute="trailing" constant="20" id="F7k-hc-PjM"/>
                            <constraint firstItem="koH-BL-KZA" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="20" id="GCM-h5-uZT"/>
                            <constraint firstItem="E2O-cv-ota" firstAttribute="top" secondItem="Wzv-3T-9rg" secondAttribute="bottom" id="HUm-Q4-lcX"/>
                            <constraint firstItem="Vfn-FR-1Ub" firstAttribute="top" secondItem="Wzv-3T-9rg" secondAttribute="bottom" id="Ifi-g7-5KM"/>
                            <constraint firstItem="WJI-4Z-VeA" firstAttribute="leading" secondItem="koH-BL-KZA" secondAttribute="trailing" constant="20" id="MZc-33-aQU"/>
                            <constraint firstAttribute="trailing" secondItem="mdf-GC-mIQ" secondAttribute="trailing" constant="154" id="Q2A-hp-SjO"/>
                            <constraint firstAttribute="trailingMargin" secondItem="Uhq-CJ-D5N" secondAttribute="trailing" constant="75" id="Taz-RX-FBH"/>
                            <constraint firstItem="LcR-MR-y9c" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="WJI-4Z-VeA" secondAttribute="trailing" symbolic="YES" id="Uor-VU-t3a"/>
                            <constraint firstItem="Vfn-FR-1Ub" firstAttribute="top" secondItem="Wzv-3T-9rg" secondAttribute="bottom" id="Wua-9B-iLw"/>
                            <constraint firstItem="koH-BL-KZA" firstAttribute="baseline" secondItem="WJI-4Z-VeA" secondAttribute="baseline" id="hB6-19-6BO"/>
                            <constraint firstItem="Vfn-FR-1Ub" firstAttribute="leading" secondItem="E2O-cv-ota" secondAttribute="trailing" constant="10" id="hY9-F7-oE8"/>
                            <constraint firstItem="mdf-GC-mIQ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="jPl-Vg-g3C" secondAttribute="trailing" symbolic="YES" id="hiz-Om-gmC"/>
                            <constraint firstAttribute="trailingMargin" secondItem="Vfn-FR-1Ub" secondAttribute="trailing" constant="10" id="nnC-yz-Mbc"/>
                            <constraint firstItem="mdf-GC-mIQ" firstAttribute="top" secondItem="LcR-MR-y9c" secondAttribute="bottom" constant="20" id="nyj-zh-x4K"/>
                            <constraint firstItem="koH-BL-KZA" firstAttribute="baseline" secondItem="LcR-MR-y9c" secondAttribute="baseline" id="uhc-hz-Lg4"/>
                            <constraint firstItem="COG-Nv-9Ga" firstAttribute="top" secondItem="vJi-oZ-LSc" secondAttribute="bottom" constant="40" id="w71-ij-wzw"/>
                            <constraint firstItem="COG-Nv-9Ga" firstAttribute="top" secondItem="Uhq-CJ-D5N" secondAttribute="bottom" constant="40" id="y0A-Wx-QLV"/>
                            <constraint firstItem="COG-Nv-9Ga" firstAttribute="top" secondItem="jPl-Vg-g3C" secondAttribute="bottom" constant="40" id="zXK-Mn-zfv"/>
                        </constraints>
                    </view>
                    <connections>
                        <outlet property="mCallOrAccept" destination="koH-BL-KZA" id="Ryl-wC-8vS"/>
                        <outlet property="monitorBtn" destination="LcR-MR-y9c" id="quQ-29-c3m"/>
                        <outlet property="speakerBtn" destination="vJi-oZ-LSc" id="gAu-k3-y1u"/>
                        <outlet property="uIDTextField" destination="Vfn-FR-1Ub" id="En1-hG-ZxX"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="131.8840579710145" y="103.79464285714285"/>
        </scene>
        <!--View Controller-->
        <scene sceneID="dmc-0p-Aa4">
            <objects>
                <viewController id="Otu-wo-FUs" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="dsY-RY-Zva"/>
                        <viewControllerLayoutGuide type="bottom" id="wHq-fg-3bZ"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="5aY-oG-FVH">
                        <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dnn-Zd-Y1M">
                                <rect key="frame" x="192" y="246" width="31" height="30"/>
                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                <state key="normal" title="跳转"/>
                                <connections>
                                    <segue destination="BYZ-38-t0r" kind="modal" id="Ipt-A0-EwF"/>
                                </connections>
                            </button>
                        </subviews>
                        <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="aje-Ad-KL1" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="-620.28985507246387" y="111.83035714285714"/>
        </scene>
    </scenes>
</document>
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/ESVideo.h
New file
@@ -0,0 +1,27 @@
//
//  ESVideo.h
//  ESVideoPhoneSDKDemo
//
//  Created by 陈嘉乐 on 2020/6/28.
//  Copyright © 2020 eTouchSky. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <ESVideoPhoneSDk/ESVideoPhone.h>
#import <ESVideoPhoneSDk/ESError.h>
NS_ASSUME_NONNULL_BEGIN
@interface ESVideo : NSObject
@property (nonatomic,strong) ESVideoPhone          *es;
@property (nonatomic, copy) ImageCallback snapImageCallback;
+ (instancetype)shareInstance;
+ (void)haltSharedInstance;
-(void)initSDK;
@end
NS_ASSUME_NONNULL_END
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/ESVideo.m
New file
@@ -0,0 +1,75 @@
//
//  ESVideo.m
//  ESVideoPhoneSDKDemo
//
//  Created by 陈嘉乐 on 2020/6/28.
//  Copyright © 2020 eTouchSky. All rights reserved.
//
#import "ESVideo.h"
#define WEAKSELF_AT __weak __typeof(&*self)weakSelf_AT = self;
@interface ESVideo()
@end
static ESVideo *_sharedInstance = nil;
static dispatch_once_t _onceToken;
@implementation ESVideo{
    ImageCallback mSnapImageCallback;
}
+ (instancetype)shareInstance {
    dispatch_once(&_onceToken, ^{
        _sharedInstance = [[ESVideo alloc] init];
        if(_sharedInstance) {
        }
        NSLog(@"ESVideo ShareInstance Did Create %p",_sharedInstance);
    });
    //NSLog(@"Access ESVideo %p",sharedInstance);
    return _sharedInstance;
}
+ (void)haltSharedInstance {
    if (_sharedInstance) {
        _sharedInstance = nil;
        _onceToken = 0;
    }
}
- (instancetype)init {
    self = [super init];
    WEAKSELF_AT
    mSnapImageCallback = ^(UIImage *image){
        if(weakSelf_AT.snapImageCallback){
            weakSelf_AT.snapImageCallback(image);
        }
    };
    //门口机会有视频的长宽高,是固定的(暂时还不确定)
    _es = [[ESVideoPhone alloc]initESVideoPhoneWithFrame: CGRectMake(10, 100, [[UIScreen mainScreen] bounds].size.width-20, ([[UIScreen mainScreen] bounds].size.width-20)/4*3) delegate:nil imagecallBack:mSnapImageCallback];
    return self;
}
- (void)dealloc {
    NSLog(@"ESVideo SharedInstance Did Halted ");
}
-(void)initSDK{
     NSLog(@"ESVideo initSDK");
}
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/Info.plist
New file
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
    <key>CFBundleShortVersionString</key>
    <string>$(MARKETING_VERSION)</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    <key>NSCameraUsageDescription</key>
    <string>"需要使用相机"</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>"需要使用麦克风"</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>"需要使用相册"</string>
    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <false/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                    <key>UISceneDelegateClassName</key>
                    <string>SceneDelegate</string>
                    <key>UISceneStoryboardFile</key>
                    <string>Main</string>
                </dict>
            </array>
        </dict>
    </dict>
    <key>UILaunchStoryboardName</key>
    <string>Main</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
</dict>
</plist>
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/SceneDelegate.h
New file
@@ -0,0 +1,16 @@
//
//  SceneDelegate.h
//  ESVideoPhoneSDKDemo
//
//  Created by eTouchSky on 2019/9/27.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>
@property (strong, nonatomic) UIWindow * window;
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/SceneDelegate.m
New file
@@ -0,0 +1,50 @@
#import "SceneDelegate.h"
@interface SceneDelegate ()
@end
@implementation SceneDelegate
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
}
- (void)sceneDidDisconnect:(UIScene *)scene {
    // Called as the scene is being released by the system.
    // This occurs shortly after the scene enters the background, or when its session is discarded.
    // Release any resources associated with this scene that can be re-created the next time the scene connects.
    // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
- (void)sceneDidBecomeActive:(UIScene *)scene {
    // Called when the scene has moved from an inactive state to an active state.
    // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
- (void)sceneWillResignActive:(UIScene *)scene {
    // Called when the scene will move from an active state to an inactive state.
    // This may occur due to temporary interruptions (ex. an incoming phone call).
}
- (void)sceneWillEnterForeground:(UIScene *)scene {
    // Called as the scene transitions from the background to the foreground.
    // Use this method to undo the changes made on entering the background.
}
- (void)sceneDidEnterBackground:(UIScene *)scene {
    // Called as the scene transitions from the foreground to the background.
    // Use this method to save data, release shared resources, and store enough scene-specific state information
    // to restore the scene back to its current state.
}
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/ViewController.h
New file
@@ -0,0 +1,23 @@
//
//  ViewController.h
//  ESVideoPhoneSDKDemo
//
//  Created by eTouchSky on 2019/9/27.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
/*
[2019.12.12 15:56:16.217#40455][SendCustomData](/Users/maygion/corelooper/projects.oem/libvideophone/src/phone/phoneconnect.cpp:942)
###Warning[2019.12.12 15:56:16.217#40455][recv custom data=[{"command":"open","room_id":1234,"devType":7,"status":1}]](/Users/maygion/corelooper/projects.oem/libvideophone/src/phone/phoneconnect.cpp:1121)
2019-12-12 15:56:16.218004+0800 ESVideoPhoneSDKDemo[1724:882637] -[ESVideoPhone onPhoneEvent_UI:],msg=event=EVT_RECV_CUSTOM_DATA
data=eyJjb21tYW5kIjoib3BlbiIsInJvb21faWQiOjEyMzQsImRldlR5cGUiOjcsInN0YXR1cyI6MX0=
2019-12-12 15:56:16.218201+0800 ESVideoPhoneSDKDemo[1724:882637] 事件EVT_RECV_CUSTOM_DATA
*/
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/ViewController.mm
New file
@@ -0,0 +1,580 @@
//
//  ViewController.m
//  ESVideoPhoneSDKDemo
//
//  Created by eTouchSky on 2019/9/27.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
/*
 ⚠️
 1、编译设置,
 BuildSettings设置 :
 Enable Bitcode 设置为NO;
 Other Linker Flags 设置为-Wl,-all_load。
 2、framework
 添加系统库 libiconv2.4.0.tbd,libz.tbd,libbz2.tbd.
 3、demo仅做参考,具体请根据App的情况适时调用
 */
#import <AVFoundation/AVFoundation.h>
#import "ViewController.h"
#import <ESVideoPhoneSDk/ESVideoPhone.h>
#import <ESVideoPhoneSDk/ESError.h>
#import "AudioSessionHelper.h"
#import "ESVideo.h"
@interface ViewController ()<ESVideoPhoneDelegate,UITextFieldDelegate>
@property (nonatomic,strong) AudioSessionHelper    *sessionHelper;
@property (nonatomic,strong) ESVideoPhone          *es;
@property (nonatomic,assign) BOOL                  playing;
@property (nonatomic,assign) BOOL                  isInterrupt;
@property (nonatomic,assign) BOOL                  isSpeaking;
@property (nonatomic,strong) UIImage               *snapImage; //截图
@property (weak, nonatomic) IBOutlet UIButton *speakerBtn;
@property (weak, nonatomic) IBOutlet UITextField *uIDTextField;
@property (weak, nonatomic) IBOutlet UIButton *mCallOrAccept;
@property (weak, nonatomic) IBOutlet UIButton *monitorBtn;
@end
@implementation ViewController
{
    BOOL isAccessAudio;
    BOOL isAccessVideo;
    BOOL isBackGround;
    BOOL iSVideoNotDetermined;
    BOOL iSAudioNotDetermined;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [ESVideo.shareInstance initSDK];
    //初始化中断,进入后台的tag
    _playing = NO;
    _isSpeaking = NO;
    self.isInterrupt = NO;
    _es = ESVideo.shareInstance.es;
    _es.isInterrupt = NO;
    isBackGround = NO;
    [_speakerBtn setTitle:@"听筒" forState:UIControlStateNormal];
//    _mCallOrAccept.enabled = NO;
//    _monitorBtn.enabled = NO;
//    _uIDTextField.text = @"JJY000016YWECG";//@"JJY000007FSEYX" 默认门口机的ID
//       _uIDTextField.text = @"JJY000017XLUXX";//@"JJY000007FSEYX" 默认门口机的ID
    _uIDTextField.text = @"JJY000019VPLLF";//@"JJY000019VPLLF" 默认门口机的ID
//           _uIDTextField.text = @"JJY000016YWECG";//@"JJY000016YWECG" 默认门口机的ID
    _uIDTextField.delegate = self;    //⚠️这里必须要检查是否已经授权否则会失败,初始化视频音频采集
    [self requestAccessForAVMediaType:AVMediaTypeAudio];
     if (isAccessAudio) {
        ImageCallback snapImageCallback = ^(UIImage *image){
             //block是在分线程中调用的,这里要放到主线程
             dispatch_async(dispatch_get_main_queue(), ^{
                 self->_snapImage = image;
                 [self saveImage:image];
             });
         };
         //门口机会有视频的长宽高,是固定的(暂时还不确定)
//         _es = [[ESVideoPhone alloc]initESVideoPhoneWithFrame:CGRectMake(10, 100, self.view.frame.size.width-20, (self.view.frame.size.width-20)/4*3) delegate:self imagecallBack:snapImageCallback];
         if (_es) {
             //判断视频渲染是否初始化成功,如果失败会走ESVideoPhoneDelegate方法
             if (_es.showView) {
//                 _es.showView.frame = CGRectMake(10, 100, self.view.frame.size.width-20, (self.view.frame.size.width-20)/4*3);
                 ESVideo.shareInstance.snapImageCallback = snapImageCallback;
                 _es.showView.backgroundColor = [UIColor greenColor];
                 _es.delegate = self;
                 [self.view addSubview:_es.showView];
             }else{
                 NSLog(@"_es.showView null");
             }
         }else{
             NSLog(@"ESVideoPhone 初始化失败");
             return;
         }
         // 初始化Audio采集Unit
         if(![_es initAudioCaptureSession]){
             return;
         }
     }else{
         //音频没有权限建议不要发起通话
         return;
     }
    //初始化视频采集Capture
    [self requestAccessForAVMediaType:AVMediaTypeVideo];
    if (isAccessVideo) {
        if(![_es initVideoCaptureSession]){
            NSLog(@"VideoCaptureSession 初始化失败");
        }
    }
    //初始化AudioSession
    _sessionHelper = [[AudioSessionHelper alloc]init];
    [_sessionHelper setAudioSession];
    //添加进入后台,中断等通知
    [self addObservers];
}
-(void)viewDidAppear:(BOOL)animated{
    //这个方法请根据App的具体情况调用
    //在viewDidLoad中 调用requestAccessForAVMediaType: 是为了节约初始化的时间
    //在viewDidAppear中调用requestAccessForAVMediaType: 是为了弹出提示打开权限的Alert
//测试的时候发现如下情况:如果只把授权方法放到ViewDidAppear方法中处理,如果没有授权在初始化采集器时会失败。同样AlertView会因为View没有didLoad而导致present不出来
    if (!isAccessVideo || !isAccessAudio) {
        [self requestAccessForAVMedia];
    }
}
-(void)setIsInterrupt:(BOOL)isInterrupt{
    if (_es) {
        _es.isInterrupt = isInterrupt;
    }
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    //防止用户不按挂断,或者不等收到对方的挂断,点击返回按钮。
    [_es onStopCapture];
    [_es stopTalk];
}
-(void)dealloc{
    _es.delegate = nil;
//    _es.showView
      NSLog(@"==============dealloc1");
    [[NSNotificationCenter defaultCenter] removeObserver:self];
      NSLog(@"==============dealloc2");
//    [_es freeSubClass];
      NSLog(@"==============dealloc3");
}
#pragma mark ButtonAction
- (IBAction)back:(id)sender {
    [self dismissViewControllerAnimated:YES completion:NULL];
}
//反呼:模拟门口机呼叫手机,需要门口机先点呼叫,等1-2S后,手机点反呼。
//params样本 address=192.168.1.3:8554,tag=mobile://123,
- (IBAction)onReverseCall:(id)sender {
    NSString *title = [sender titleForState:UIControlStateNormal];
    if ([title isEqualToString:@"反呼"]) {
       NSString *normalStr = _uIDTextField.text;
       NSString *param = [NSString stringWithFormat:@"address=%@,tag=mobile://123,",normalStr];
       NSLog(@"============点反呼%@", param);
       [_es onReverseCall:param];
    }else if([title isEqualToString:@"接听"]){
        [_es onAccept];
    }
}
- (IBAction)onHangup:(id)sender {
    [_es onHangup];
}
- (IBAction)onMonitor:(id)sender {
    [_es onMonitor:_uIDTextField.text];
}
- (IBAction)speaker:(UIButton *)sender {
    [_es stopTalk];
      NSString *result = nil;
      //听筒状态 插耳塞后拔掉后恢复到默认设置
      if (sender == nil) {
          result = [_sessionHelper speaker:NO];
      }else{
          if(!_isSpeaking){
              result = [_sessionHelper speaker:YES];
              _isSpeaking = YES;
          }else{
              result = [_sessionHelper speaker:NO];
              _isSpeaking = NO;
          }
      }
      if (result) {
          [sender setTitle:result forState:UIControlStateNormal];
          [_es startTalk];
      }
}
- (IBAction)openDoor:(id)sender {
    [_es openTheDoorWithRoomid: 1234];
}
- (IBAction)onSnap:(id)sender {
    [_es onSnap];
}
//⚠️ 文本输入框
#pragma mark ESVideoPhoneDelegate
//视频通话的状态代理事件,phoneEvent为返回的消息里面包含event状态与与event相关的数据
-(void)getPhoneEvent_UI:(NSString *)phoneEvent{
    NSLog(@"事件%@", phoneEvent);
    NSArray *strArray = [phoneEvent componentsSeparatedByString:@"\r\n"];
    NSArray *eventArray = [strArray.firstObject componentsSeparatedByString:@"="];
    NSString *phoneEventStr = eventArray.lastObject;
    if([phoneEventStr isEqual:@"EVT_Ringing"]){
           [_mCallOrAccept setTitle:@"接听" forState:UIControlStateNormal];
       }else if([phoneEventStr isEqual:@"EVT_StartStream"]){
       } else if([phoneEventStr isEqual:@"EVT_StopStream"]){
           [_mCallOrAccept setTitle:@"反呼" forState:UIControlStateNormal];
       }else if([phoneEventStr isEqual:@"EVT_Connected"]){
           [_mCallOrAccept setTitle:@"通话中..." forState:UIControlStateNormal];
       }else if([phoneEventStr  isEqual:@"EVT_HangUp"]){
           [_mCallOrAccept setTitle:@"反呼" forState:UIControlStateNormal];
       }else if([phoneEventStr  isEqual:@"EVT_P2POnlineStatusChanged"]){
           //EVT_P2PStarted(p2p初始化OK,可以连接),EVT_P2POnlineStatusChangedonline=1
           //p2p初始化成功,手机端目前没有这个回调了
          //_mCallOrAccept.enabled = YES;
          //_monitorBtn.enabled = YES;
       }else if([phoneEventStr  isEqual:@"EVT_RECV_CUSTOM_DATA"]){
           //开门的结果从这里返回
           NSString *baseStr = [strArray[1] substringFromIndex:5];
           NSData *data = [[NSData alloc]initWithBase64EncodedString:baseStr options:NSDataBase64DecodingIgnoreUnknownCharacters];
           NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
           NSInteger status = [[dic valueForKey:@"status"]integerValue];
             if(status && status == 1){
                 NSLog(@"开门成功");
             }else{
                 NSLog(@"开门失败");
             }
       }
}
-(void)getAErrorForESVideoPhone:(NSString *)errorStr type:(NSUInteger)errortype{
    NSLog(@"错误%@", errorStr);
    //没有授权
    if (errortype == LMPVideoCaptureErrorNotAuthorized) {
        NSLog(@"错误%@", errorStr);
    }
}
#pragma mark AudioSession与Notifications处理
- (void) addObservers
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name: UIKeyboardWillChangeFrameNotification  object: nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:nil];
    //isAccessVideo,如果AVCaptureSession没有new出来不会收到通知
    if (isAccessVideo) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionWasInterrupted:) name:AVCaptureSessionWasInterruptedNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionInterruptionEnded:) name:AVCaptureSessionInterruptionEndedNotification object:nil];
    }else{
        //object:为nil 可能不会触发通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:)
            name:AVAudioSessionInterruptionNotification object:[AVAudioSession
            sharedInstance]];
    }
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:)   name:AVAudioSessionRouteChangeNotification object:nil];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterForeground:) name:UIApplicationDidBecomeActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
}
- (void) sessionRuntimeError:(NSNotification*)notification
{
    NSError* error = notification.userInfo[AVCaptureSessionErrorKey];
    NSLog(@"Capture session runtime error: %@", error);
    // If media services were reset, and the last start succeeded, restart the session.
    if (error.code == AVErrorMediaServicesWereReset) {
        [_es onStopCapture];
        [_es startTalk];
    }
}
- (void)handleInterruption:(NSNotification *)notification
{
    NSUInteger interruptionType = [[[notification userInfo]
                                                        objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
    if (AVAudioSessionInterruptionTypeBegan == interruptionType)
    {
      if (isBackGround) {
          return;
      }
        [_es stopTalk];
    }
    else if (AVAudioSessionInterruptionTypeEnded == interruptionType)
    {
      if (self.isInterrupt == NO) {
          return;
      }else{
          //直接在进入前台那个通知里面实现,实际上进入前台的方法会在这个方法前面调用,效果更好
          [self InterruptionEndedAVAudioSessionSetActiveYES];
      }
    }
}
//AVAudioPlayer 类和 AVAudioRecorder 类,当发生中断时,系统会自动暂停播放或录制
- (void) sessionWasInterrupted:(NSNotification*)notification
{
    if (_playing == YES) {
        self.isInterrupt = YES;
       //AVCaptureSessionInterruptionReason
        if (@available(iOS 9.0, *)) {
            NSInteger reason = [notification.userInfo[AVCaptureSessionInterruptionReasonKey] integerValue]; //电话中断是1
            NSLog(@"Capture session was interrupted with reason %ld", (long)reason);
            //音频硬件暂时不可用而造成的中断,例如,电话或警报。
            if (reason == AVCaptureSessionInterruptionReasonAudioDeviceInUseByAnotherClient ||
                reason == AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient) {
                NSLog(@"AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient");
                //VAudioPlayer 类和 AVAudioRecorder 类,当发生中断时,系统会自动暂停播放或录制
                //Audio Queue Services, I/O audio unit
                [_es onStopCapture];
                [_es stopTalk];
                /*
                 NSError *error = nil;
                 [[AVAudioSession sharedInstance] setActive:NO error:&error];
                 if (error) {
                 NSLog(@"sessionWasInterruptedSetActiveNO error:%@", error);
                 }
                 */
            }else if (reason == AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableInBackground){
                NSLog(@"AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableInBackground");
                //如果是电话中断,不会走进入后台的通知,进入后台再切换到前台这里是不用处理的
                if (isBackGround) {
                    return;
                }
                [_es onStopCapture];
                [_es stopTalk];
            }
            //多个应用程序资源争用质量下降。只有当应用程序占据全屏时,会话才能运行。
            else if (reason == AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps) {
                NSLog(@"AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps");
                // Fade-in a label to inform the user that the camera is unavailable.
            }else if (@available(iOS 11.1, *)) {
                if (reason == AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableDueToSystemPressure){
                    NSLog(@"AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableDueToSystemPressure");
                }
            } else {
                // Fallback on earlier versions
            }
        } else {
            if (isBackGround) {
                return;
            }
            [_es onStopCapture];
            [_es stopTalk];
        }
    }
}
//这个通知可能会获取不到,
- (void) sessionInterruptionEnded:(NSNotification*)notification
{
//    NSInteger reason = [notification.userInfo[AVCaptureSessionInterruptionReasonKey] integerValue];
    NSLog(@"Capture session interruption ended");
    if (self.isInterrupt == NO) {
        return;
    }else{
        //直接在进入前台那个通知里面实现,实际上进入前台的方法会在这个方法前面调用,效果更好
        [self InterruptionEndedAVAudioSessionSetActiveYES];
    }
}
-(void)InterruptionEndedAVAudioSessionSetActiveYES{
    if (isBackGround) {
        return;
    }
    if (self.isInterrupt == YES) {
        [_es onStartCapture];
        [_es startTalk];
        self.isInterrupt = NO;
    }
}
- (void)audioRouteChangeListenerCallback:(NSNotification*)notification
{
    NSDictionary *interuptionDict = notification.userInfo;
    NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
    switch (routeChangeReason) {
        case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
           //NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable");
            //免提状态下耳机插入没有采集,同意切换到默认状态
            NSLog(@"耳机插入");
            [self speaker:nil];
            break;
        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
            //NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
            NSLog(@"耳机拔出");
            if([[_speakerBtn titleForState:UIControlStateNormal] isEqualToString:@"免提"]){
                 [self speaker:nil];
            }else{
                [self speaker:_speakerBtn];
            }
            break;
        case AVAudioSessionRouteChangeReasonCategoryChange:
            // called at start - also when other audio wants to play
            //NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange");
            break;
    }
}
/*
 需要注意的是,有一个中断开始消息不一定会有一个中断结束消息,这就意味着中断结束的回调里的处理逻辑可能会没有被执行到。
 所以需要关注当切到前台运行状态时,是不是需要重新激活你的 Audio Session。
 */
- (void)willEnterForeground:(NSNotification*)notification{
     NSLog(@"willEnterForeground");
    //初次启动会走这个通知(根页面),这时候是没有进入后台的
    if (isBackGround) {
        return;
    }
    [self InterruptionEndedAVAudioSessionSetActiveYES];
    // 这里是考虑到用户没有授权,之后通过AlertAction跳转到设置页面授权后再回到APP时做的重新检测
    //跳转到设置页面,授权后返回页面,继续初始化采集器
    if (isAccessAudio && isAccessVideo) {
        return;
    }
    if (isAccessVideo && !isAccessAudio) {
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
        if (isAccessAudio) {
            [_es initAudioCaptureSession];
        }
    }else if (!isAccessVideo && isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
        if (isAccessVideo) {
            [_es initVideoCaptureSession];
        }
    }else if (!isAccessVideo && !isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
        if (isAccessAudio) {
            [_es initAudioCaptureSession];
        }
        if (isAccessVideo) {
            [_es initVideoCaptureSession];
        }
    }
}
- (void)willEnterBackground:(NSNotification *)notification {
    isBackGround = YES;
}
//授权Alert
-(void)requestAccessForAVMedia{
    if (!isAccessAudio) {
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
    }
    if (!isAccessVideo) {
         [self requestAccessForAVMediaType:AVMediaTypeVideo];
    }
    if (!iSAudioNotDetermined && iSVideoNotDetermined){
        [self creatAlertViewWith:@"授权请求" message:@"麦克风没有授权,请在设置中开启权限,否则将影响通讯功能。" cancel:@"确定"];
    }else if(iSAudioNotDetermined && !iSVideoNotDetermined){
        [self creatAlertViewWith:@"授权请求" message:@"相机没有授权,请在设置中开启权限,否则将影响通讯功能。" cancel:@"确定"];
    }else if(!iSAudioNotDetermined && !iSVideoNotDetermined){
        [self creatAlertViewWith:@"授权请求" message:@"麦克风与相机授权,请在设置中开启权限,否则将影响通讯功能。" cancel:@"确定"];
    }
}
-(void)requestAccessForAVMediaType:(AVMediaType)type{
    if (type == AVMediaTypeVideo) {
        isAccessVideo = YES;
        iSVideoNotDetermined = YES;
    }else{
        isAccessAudio = YES;
        iSAudioNotDetermined = YES;
    }
    switch ([AVCaptureDevice authorizationStatusForMediaType:type])
    {
        case AVAuthorizationStatusAuthorized:
        {
            break;
        }
        case AVAuthorizationStatusNotDetermined:
        {
            dispatch_suspend(dispatch_get_main_queue());
            [AVCaptureDevice requestAccessForMediaType:type completionHandler:^(BOOL granted) {
                if (!granted) {
                    if (type == AVMediaTypeVideo) {
                        self->isAccessVideo = NO;
                    }else{
                        self->isAccessAudio = NO;
                    }
                }
                dispatch_resume(dispatch_get_main_queue());
            }];
            break;
        }
        default:
        {
            if (type == AVMediaTypeVideo) {
                isAccessVideo = NO;
                 iSVideoNotDetermined = NO;
            }else{
                isAccessAudio = NO;
                iSAudioNotDetermined = NO;
            }
           break;
        }
    }
}
-(void)creatAlertViewWith:(NSString *)title message:(NSString *) msg cancel:(NSString *)cancelMsg{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:[UIAlertAction actionWithTitle:cancelMsg style:UIAlertActionStyleCancel handler:nil]];
    [alertController addAction:[UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    }]];
   [self presentViewController:alertController animated:YES completion:nil];
}
#pragma mark --privita 辅助
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.view endEditing:YES];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if(textField.returnKeyType == UIReturnKeyDone){
        [textField resignFirstResponder];//键盘收起
        return NO;
    }
    return YES;
}
- (void)keyboardWillChangeFrame:(NSNotification *)notification {
    NSValue *notiValue =notification.userInfo[@"UIKeyboardFrameEndUserInfoKey"];
     if(notiValue){
         CGRect rect = [notiValue CGRectValue];
         [UIView animateWithDuration:0.5 animations:^{
             if (self.view.frame.origin.y < 0) {
                 //已经上移动一次了,就不用移动了
                 if (self.view.frame.origin.y == 0){
                     CGFloat yFloat = self.view.frame.origin.y;
                     self.view.frame = CGRectMake(self.view.frame.origin.x, yFloat+50, self.view.frame.size.width, self.view.frame.size.height);
                 }
             }
             if (rect.origin.y == [UIScreen mainScreen].bounds.size.height) { //键盘将要收起
                 self.view.frame = CGRectMake(self.view.frame.origin.x, 0, self.view.frame.size.width, self.view.frame.size.height);
             }
         } completion:nil];
    }
}
- (void)saveImage:(UIImage *)image {
    NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
    NSString *filePath = [[paths objectAtIndex:0]stringByAppendingPathComponent:
                          [NSString stringWithFormat:@"demo.png"]];  // 保存文件的名称
    BOOL result =[UIImagePNGRepresentation(image)writeToFile:filePath   atomically:YES]; // 保存成功会返回YES
    if (result == YES) {
        NSLog(@"保存成功");
    }
}
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemo/main.m
New file
@@ -0,0 +1,19 @@
//
//  main.m
//  ESVideoPhoneSDKDemo
//
//  Created by eTouchSky on 2019/9/27.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemoTests/ESVideoPhoneSDKDemoTests.m
New file
@@ -0,0 +1,37 @@
//
//  ESVideoPhoneSDKDemoTests.m
//  ESVideoPhoneSDKDemoTests
//
//  Created by eTouchSky on 2019/9/27.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
#import <XCTest/XCTest.h>
@interface ESVideoPhoneSDKDemoTests : XCTestCase
@end
@implementation ESVideoPhoneSDKDemoTests
- (void)setUp {
    // Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
}
- (void)testExample {
    // This is an example of a functional test case.
    // Use XCTAssert and related functions to verify your tests produce the correct results.
}
- (void)testPerformanceExample {
    // This is an example of a performance test case.
    [self measureBlock:^{
        // Put the code you want to measure the time of here.
    }];
}
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemoTests/Info.plist
New file
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
</dict>
</plist>
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemoUITests/ESVideoPhoneSDKDemoUITests.m
New file
@@ -0,0 +1,48 @@
//
//  ESVideoPhoneSDKDemoUITests.m
//  ESVideoPhoneSDKDemoUITests
//
//  Created by eTouchSky on 2019/9/27.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
#import <XCTest/XCTest.h>
@interface ESVideoPhoneSDKDemoUITests : XCTestCase
@end
@implementation ESVideoPhoneSDKDemoUITests
- (void)setUp {
    // Put setup code here. This method is called before the invocation of each test method in the class.
    // In UI tests it is usually best to stop immediately when a failure occurs.
    self.continueAfterFailure = NO;
    // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
}
- (void)testExample {
    // UI tests must launch the application that they test.
    XCUIApplication *app = [[XCUIApplication alloc] init];
    [app launch];
    // Use recording to get started writing UI tests.
    // Use XCTAssert and related functions to verify your tests produce the correct results.
}
- (void)testLaunchPerformance {
    if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
        // This measures how long it takes to launch your application.
        [self measureWithMetrics:@[XCTOSSignpostMetric.applicationLaunchMetric] block:^{
            [[[XCUIApplication alloc] init] launch];
        }];
    }
}
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDKDemoUITests/Info.plist
New file
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
</dict>
</plist>
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/ESVideoPhoneSDk
Binary files differ
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/Headers/ESError.h
New file
@@ -0,0 +1,76 @@
//
//  ESError.h
//  ESVideoPhoneSDk
//
//  Created by eTouchSky on 2019/12/14.
//  Copyright © 2019 eTouchSky. All rights reserved.
//
//  ESVideoPhone的ESVideoPhoneDelegate方法“- (void)getAErrorForESVideoPhone:(NSString *)errorStr type:(NSUInteger) errortype” 中errortype的类型
#import <Foundation/Foundation.h>
//视频采集,会导致门口机看不到App的视频(监控状态时,门口机是看不到App的视频的)
//App需要处理 LMPVideoCaptureErrorGetDevice与LMPVideoCaptureErrorNotAuthorized 类型的错误
typedef NS_ENUM (NSUInteger, LMPVideoCaptureError){
    LMPVideoCaptureErrorGetDevice                      = 0,//获取摄像头失败
    LMPVideoCaptureErrorGetInput                       = 1,//获取视频输入错误,从error中获取具体信息
    LMPVideoCaptureErrorAddInput                       = 2,//AddInputVideo错误
    LMPVideoCaptureErrorAddOutput                      = 3,//AddOutputVideo错误
    LMPVideoCaptureErrorNotAuthorized                  = 4,//没有授权,授权处理由App实现
    LMPVideoCaptureErrorSetSessionPreset               = 5,//SetSessionPreset失败
};
//openGl视频渲染,会导致门口机看不到App的视频(监控状态时,门口机是看不到App的视频的)
typedef NS_ENUM (NSUInteger, LMPOpenglError){
    LMPOpenglErrorSetCurrentContext                      = 0,//EAGLContext上下文创建失败
    LMPOpenglErrorRenderbuffer                           = 1,//OpenGL attach渲染缓冲区失败
    LMPOpenglErrorGenTextures                            = 2,//OpenGL 纹理创建失败
    LMPOpenglErrorShaderConnection                       = 3,//OpenGL 着色器连接失败
    LMPOpenglErrorLoadShader                             = 4,//OpenGL 加载着色器失败
    LMPOpenglErrorShaderCompilation                      = 5,//OpenGL 着色器编译失败
};
/**视频解码,会导致App看不到门口机的视频
debug模式下,断点可能导致出现LMPH264HwDecoderErrorKVTInvalidSessionErr的错误
前台后切换,来电等原因的中断可能会出现LMPH264HwDecoderErrorKVTInvalidSessionErr的错误(已经修复,注意测试过程中是否还会出现)
*/
typedef NS_ENUM (NSUInteger, LMPH264HwDecoderError){
    LMPH264HwDecoderErrorInitH264HardwareDecoder                     = 0,//InitH264HardwareDecoderErr
    LMPH264HwDecoderErrorKVTVideoDecoderMalfunction                  = 1,//kVTVideoDecoderMalfunctionErr
    LMPH264HwDecoderErrorKVTInvalidSessionErr                        = 2,//kVTInvalidSessionErr
    LMPH264HwDecoderErrorKVTVideoDecoderBadDataErr                   = 3,//kVTVideoDecoderBadDataErr
    LMPH264HwDecoderErrorDecodeOtherErr                              = 4,//硬解码其他错误
    LMPH264HwDecoderErrorCVPixelBufferRefPlantErr                    = 5,//CVPixelBufferRef中数据为空
    LMPH264HwDecoderErrorCVPixelBufferRefYUVErr                      = 6,//CVPixelBufferRef中取出YUV失败
};
//视频编码,会导致门口机看不到App的视频(监控状态时,门口机是看不到App的视频的)
typedef NS_ENUM (NSUInteger, LMPH264EncoderError){
    LMPH264EncoderErrorVTCompressionSessionCreate                    = 0,//VTCompressionSessionCreateErr
    LMPH264EncoderErrorVideoCompressonOutputCallback                 = 1,//编码回调失败
};
//音频采集,会导致不能采集音频,对方听不到App的声音(监控状态时,门口机是听不到App的声音的)
typedef NS_ENUM (NSUInteger, LMPAudioCaptureError){
    LMPAudioCaptureErrorGetNew                         = 0,//AudioComponentInstanceNew失败
    LMPAudioCaptureErrorStreamFormat                   = 1,//kAudioUnitProperty_StreamFormat失败
    LMPAudioCaptureErrorEnableRecord                   = 2,//打开录音失败
    LMPAudioCaptureErrorEnablePlay                     = 3,//关闭播放失败
    LMPAudioCaptureErrorSetInputCallback               = 4,//AudioUnitSetCallback失败
    LMPAudioCaptureErrorShouldAllocateBuffer           = 5,//使用自己的缓存失败
    LMPAudioCaptureErrorBypassVoiceProcessing          = 6,//打开回声消除功能失败
    LMPAudioCaptureErrorAudioUnitInitialize          = 7,//AudioUnitInitialize失败
};
//音频播放,会导致不能播放音频,听不到对方的声音
typedef NS_ENUM (NSUInteger, LMPAudioPlayError){
    LMPAudioPlayErrorGetNew                         = 0,//AudioPlay_AudioComponentInstanceNew失败
    LMPAudioPlayErrorStreamFormat                   = 1,//AudioPlay_kAudioUnitProperty_StreamFormat失败
    LMPAudioPlayErrorEnableRecord                   = 2,//AudioPlay_关闭录音失败
    LMPAudioPlayErrorEnablePlay                     = 3,//AudioPlay_打开播放失败
    LMPAudioPlayErrorSetRenderCallback              = 4,//AudioPlay_AudioUnitSetRenderCallback失败
    LMPAudioPlayErrorShouldAllocateBuffer           = 5,//使用自己的缓存失败
    LMPAudioPlayErrorBypassVoiceProcessing          = 6,//AudioPlay_打开回声消除功能失败
    LMPAudioPlayErrorAudioUnitInitialize            = 7,//AudioPlay_AudioUnitInitialize失败
};
@interface ESError : NSObject
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/Headers/ESVideoPhone.h
New file
@@ -0,0 +1,83 @@
//  ESVideoPhone.h
//  VideoPhone
//
//  Created by maygion on 2019/3/26.
//  Copyright © 2019 eTouchSky. All rights reserved.
//  SDK版本号:1.0.0  测试版1
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef void (^ImageCallback)(UIImage *image);
@protocol ESVideoPhoneDelegate <NSObject>
- (void)getAErrorForESVideoPhone:(NSString *)errorStr type:(NSUInteger) errortype;
- (void)getPhoneEvent_UI:(NSString*)phoneEvent;
@end
@interface ESVideoPhone : NSObject
//错误信息
@property(nonatomic,weak) id<ESVideoPhoneDelegate> delegate;
////获取视频截图的block
//@property(nonatomic,copy) ImageCallback snapImageCallback;
//视频显示的View ⚠️请做非空判断
@property(nonatomic,strong,readonly) UIView* showView;
//中断设置
@property (nonatomic,assign,readwrite) BOOL isInterrupt;
/**
* ESVideoPhone 初始化方法
*
* @param frame 生成显示视频的CGRect
* @param delegate ESVideoPhoneDelegate代理
* @paramimagecallBack 获取视频截图的block
*
*  @return ESVideoPhone 实例,返回nil表示初始化失败。
*/
- (instancetype)initESVideoPhoneWithFrame:(CGRect)frame delegate: (id<ESVideoPhoneDelegate>)del imagecallBack:(ImageCallback)callBack;
//授权后打开音频采集,视频没有权限也可以只音频通话
-(BOOL)initAudioCaptureSession;
//⚠️授权后打开视频采集,音频没有权限建议不要发起通话
-(BOOL)initVideoCaptureSession;
/**
* 监控
*
* @param deviceId 门口机设备ID,这个参数会从后台拉取(一般是个数组其中包含该用户权限拥有的所有门口机)
*/
- (void)onMonitor:(NSString *)deviceId;
/**
* 接听
* 这个方法会在AppDelegate的通知接口中调用,采用小米推送
* @param deviceId 门口机设备ID,这个参数会从通知中获取由设备ID与单次通话tag拼成(可能会有变动)
*/
- (void)onReverseCall:(NSString *)deviceId;
//接听
- (void)onAccept;
//挂断
- (void)onHangup;
//打开音频采集与音频播放
-(void)startTalk;
//关闭音频采集与音频播放
- (void)stopTalk;
//获取视频截图
- (void)onSnap;
//打开视频采集
- (void)onStartCapture;
//关闭视频采集
- (void)onStopCapture;
/**
* 开门,结果在ESVideoPhoneDelegate 方法中返回
*
* @param roomId 住户的roomid)
*/
-(void)openTheDoorWithRoomid: (int)roomId;
//释放资源(delegate释放等)
-(void)freeSubClass;
@end
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/Info.plist
Binary files differ
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/_CodeSignature/CodeDirectory
Binary files differ
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements
Binary files differ
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements-1
Binary files differ
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/_CodeSignature/CodeResources
New file
@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>files</key>
    <dict>
        <key>Headers/ESError.h</key>
        <data>
        6x23lohs1gRaX2F7raZcezxZt4A=
        </data>
        <key>Headers/ESVideoPhone.h</key>
        <data>
        PXntC+GjEn5A+q23YZHDZYIGj3k=
        </data>
        <key>Info.plist</key>
        <data>
        pac6jrrTIT3Ur/3XHh3CoCOUlnE=
        </data>
    </dict>
    <key>files2</key>
    <dict>
        <key>Headers/ESError.h</key>
        <dict>
            <key>hash</key>
            <data>
            6x23lohs1gRaX2F7raZcezxZt4A=
            </data>
            <key>hash2</key>
            <data>
            y8ReVa9YaZ6fyPjy8EeTl3jbaUadZUYVC0IdLJ/HrgM=
            </data>
        </dict>
        <key>Headers/ESVideoPhone.h</key>
        <dict>
            <key>hash</key>
            <data>
            PXntC+GjEn5A+q23YZHDZYIGj3k=
            </data>
            <key>hash2</key>
            <data>
            MboPVH5djlpgR//Z7UcRBMEeaakW6FWQbZxlkx4KzaM=
            </data>
        </dict>
    </dict>
    <key>rules</key>
    <dict>
        <key>^.*</key>
        <true/>
        <key>^.*\.lproj/</key>
        <dict>
            <key>optional</key>
            <true/>
            <key>weight</key>
            <real>1000</real>
        </dict>
        <key>^.*\.lproj/locversion.plist$</key>
        <dict>
            <key>omit</key>
            <true/>
            <key>weight</key>
            <real>1100</real>
        </dict>
        <key>^Base\.lproj/</key>
        <dict>
            <key>weight</key>
            <real>1010</real>
        </dict>
        <key>^version.plist$</key>
        <true/>
    </dict>
    <key>rules2</key>
    <dict>
        <key>.*\.dSYM($|/)</key>
        <dict>
            <key>weight</key>
            <real>11</real>
        </dict>
        <key>^(.*/)?\.DS_Store$</key>
        <dict>
            <key>omit</key>
            <true/>
            <key>weight</key>
            <real>2000</real>
        </dict>
        <key>^.*</key>
        <true/>
        <key>^.*\.lproj/</key>
        <dict>
            <key>optional</key>
            <true/>
            <key>weight</key>
            <real>1000</real>
        </dict>
        <key>^.*\.lproj/locversion.plist$</key>
        <dict>
            <key>omit</key>
            <true/>
            <key>weight</key>
            <real>1100</real>
        </dict>
        <key>^Base\.lproj/</key>
        <dict>
            <key>weight</key>
            <real>1010</real>
        </dict>
        <key>^Info\.plist$</key>
        <dict>
            <key>omit</key>
            <true/>
            <key>weight</key>
            <real>20</real>
        </dict>
        <key>^PkgInfo$</key>
        <dict>
            <key>omit</key>
            <true/>
            <key>weight</key>
            <real>20</real>
        </dict>
        <key>^embedded\.provisionprofile$</key>
        <dict>
            <key>weight</key>
            <real>20</real>
        </dict>
        <key>^version\.plist$</key>
        <dict>
            <key>weight</key>
            <real>20</real>
        </dict>
    </dict>
</dict>
</plist>
ESVideoPhoneSDKDemo1.3/ESVideoPhoneSDKDemo/ESVideoPhoneSDk.framework/_CodeSignature/CodeSignature
Binary files differ
ESVideoPhoneSDKZigbee/ESVideoPhoneSDKDemo/ZigBee/ESVideoMonitorViewController.m
@@ -120,7 +120,7 @@
    UIView *TopView =  [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, APP_TOP_BAR_HEIGHT)];
    TopView.backgroundColor = HEXCOLORA(0xF9F9F9,1.0);
    [TopView addSubview:self.backButton];
    [TopView addSubview:self.moreButton];
//    [TopView addSubview:self.moreButton];
    [self.view addSubview:TopView];
    TopView.layer.shadowColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.25].CGColor;
    TopView.layer.shadowOffset = CGSizeMake(0,0.5);
@@ -445,12 +445,12 @@
        return;
    }
    //初始化视频采集Capture
    [self requestAccessForAVMediaType:AVMediaTypeVideo];
    if (isAccessVideo) {
        if(![_es initVideoCaptureSession]){
            NSLog(@"VideoCaptureSession 初始化失败");
        }
    }
//    [self requestAccessForAVMediaType:AVMediaTypeVideo];
//    if (isAccessVideo) {
//        if(![_es initVideoCaptureSession]){
//            NSLog(@"VideoCaptureSession 初始化失败");
//        }
//    }
    //初始化AudioSession
    _sessionHelper = [[AudioSessionHelper alloc]init];
    [_sessionHelper setAudioSession];
@@ -512,7 +512,12 @@
    //在viewDidLoad中 调用requestAccessForAVMediaType: 是为了节约初始化的时间
    //在viewDidAppear中调用requestAccessForAVMediaType: 是为了弹出提示打开权限的Alert
    //测试的时候发现如下情况:如果只把授权方法放到ViewDidAppear方法中处理,如果没有授权在初始化采集器时会失败。同样AlertView会因为View没有didLoad而导致present不出来
    if (!isAccessVideo || !isAccessAudio) {
//    if (!isAccessVideo || !isAccessAudio) {
//        [self requestAccessForAVMedia];
//    }
    if (!isAccessAudio) {
        [self requestAccessForAVMedia];
    }
}
@@ -831,30 +836,37 @@
    
    // 这里是考虑到用户没有授权,之后通过AlertAction跳转到设置页面授权后再回到APP时做的重新检测
    //跳转到设置页面,授权后返回页面,继续初始化采集器
    if (isAccessAudio && isAccessVideo) {
        return;
    }
    if (isAccessVideo && !isAccessAudio) {
    if(!isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
        if (isAccessAudio) {
            [_es initAudioCaptureSession];
        }
    }else if (!isAccessVideo && isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
        if (isAccessVideo) {
            [_es initVideoCaptureSession];
        }
    }else if (!isAccessVideo && !isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
        if (isAccessAudio) {
            [_es initAudioCaptureSession];
        }
        if (isAccessVideo) {
            [_es initVideoCaptureSession];
        }
    }
//    if (isAccessAudio && isAccessVideo) {
//        return;
//    }
//    if (isAccessVideo && !isAccessAudio) {
//        [self requestAccessForAVMediaType:AVMediaTypeAudio];
//        if (isAccessAudio) {
//            [_es initAudioCaptureSession];
//        }
//    }else if (!isAccessVideo && isAccessAudio){
////        [self requestAccessForAVMediaType:AVMediaTypeVideo];
////        if (isAccessVideo) {
////            [_es initVideoCaptureSession];
////        }
//
//    }else if (!isAccessVideo && !isAccessAudio){
//        [self requestAccessForAVMediaType:AVMediaTypeAudio];
////        [self requestAccessForAVMediaType:AVMediaTypeVideo];
//        if (isAccessAudio) {
//            [_es initAudioCaptureSession];
//        }
////        if (isAccessVideo) {
////            [_es initVideoCaptureSession];
////        }
//    }
}
- (void)willEnterBackground:(NSNotification *)notification {
    isBackGround = YES;
@@ -865,9 +877,9 @@
    if (!isAccessAudio) {
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
    }
    if (!isAccessVideo) {
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
    }
//    if (!isAccessVideo) {
////        [self requestAccessForAVMediaType:AVMediaTypeVideo];
//    }
    if (!iSAudioNotDetermined && iSVideoNotDetermined){
        [self creatAlertViewWith:@"授权请求" message:@"麦克风没有授权,请在设置中开启权限,否则将影响通讯功能。" cancel:@"确定"];
    }else if(iSAudioNotDetermined && !iSVideoNotDetermined){
ESVideoPhoneSDKZigbee/ESVideoPhoneSDKDemo/ZigBee/ESvideoVideoIntercomViewController.m
@@ -137,7 +137,7 @@
    UIView *TopView =  [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, APP_TOP_BAR_HEIGHT)];
    TopView.backgroundColor = HEXCOLORA(0xF9F9F9,1.0);
    //    [TopView addSubview:self.backButton];
    [TopView addSubview:self.moreButton];
//    [TopView addSubview:self.moreButton];
    [self.view addSubview:TopView];
    TopView.layer.shadowColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.25].CGColor;
    TopView.layer.shadowOffset = CGSizeMake(0,0.5);
@@ -632,12 +632,12 @@
        return;
    }
    //初始化视频采集Capture
    [self requestAccessForAVMediaType:AVMediaTypeVideo];
    if (isAccessVideo) {
        if(![_es initVideoCaptureSession]){
            NSLog(@"VideoCaptureSession 初始化失败");
        }
    }
//    [self requestAccessForAVMediaType:AVMediaTypeVideo];
//    if (isAccessVideo) {
//        if(![_es initVideoCaptureSession]){
//            NSLog(@"VideoCaptureSession 初始化失败");
//        }
//    }
    //初始化AudioSession
    _sessionHelper = [[AudioSessionHelper alloc]init];
    [_sessionHelper setAudioSession];
@@ -720,7 +720,11 @@
    //在viewDidLoad中 调用requestAccessForAVMediaType: 是为了节约初始化的时间
    //在viewDidAppear中调用requestAccessForAVMediaType: 是为了弹出提示打开权限的Alert
    //测试的时候发现如下情况:如果只把授权方法放到ViewDidAppear方法中处理,如果没有授权在初始化采集器时会失败。同样AlertView会因为View没有didLoad而导致present不出来
    if (!isAccessVideo || !isAccessAudio) {
//    if (!isAccessVideo || !isAccessAudio) {
//        [self requestAccessForAVMedia];
//    }
//
    if (!isAccessAudio) {
        [self requestAccessForAVMedia];
    }
}
@@ -1021,30 +1025,37 @@
    
    // 这里是考虑到用户没有授权,之后通过AlertAction跳转到设置页面授权后再回到APP时做的重新检测
    //跳转到设置页面,授权后返回页面,继续初始化采集器
    if (isAccessAudio && isAccessVideo) {
        return;
    }
    if (isAccessVideo && !isAccessAudio) {
    if(!isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
        if (isAccessAudio) {
            [_es initAudioCaptureSession];
        }
    }else if (!isAccessVideo && isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
        if (isAccessVideo) {
            [_es initVideoCaptureSession];
        }
    }else if (!isAccessVideo && !isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
        if (isAccessAudio) {
            [_es initAudioCaptureSession];
        }
        if (isAccessVideo) {
            [_es initVideoCaptureSession];
        }
    }
//    if (isAccessAudio && isAccessVideo) {
//        return;
//    }
//    if (isAccessVideo && !isAccessAudio) {
//        [self requestAccessForAVMediaType:AVMediaTypeAudio];
//        if (isAccessAudio) {
//            [_es initAudioCaptureSession];
//        }
//    }else if (!isAccessVideo && isAccessAudio){
////        [self requestAccessForAVMediaType:AVMediaTypeVideo];
////        if (isAccessVideo) {
////            [_es initVideoCaptureSession];
////        }
//
//    }else if (!isAccessVideo && !isAccessAudio){
//        [self requestAccessForAVMediaType:AVMediaTypeAudio];
////        [self requestAccessForAVMediaType:AVMediaTypeVideo];
//        if (isAccessAudio) {
//            [_es initAudioCaptureSession];
//        }
////        if (isAccessVideo) {
////            [_es initVideoCaptureSession];
////        }
//    }
}
- (void)willEnterBackground:(NSNotification *)notification {
    isBackGround = YES;
@@ -1055,9 +1066,9 @@
    if (!isAccessAudio) {
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
    }
    if (!isAccessVideo) {
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
    }
//    if (!isAccessVideo) {
//        [self requestAccessForAVMediaType:AVMediaTypeVideo];
//    }
    if (!iSAudioNotDetermined && iSVideoNotDetermined){
        [self creatAlertViewWith:@"授权请求" message:@"麦克风没有授权,请在设置中开启权限,否则将影响通讯功能。" cancel:@"确定"];
    }else if(iSAudioNotDetermined && !iSVideoNotDetermined){
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/ESVideoPhoneSDk
Binary files differ
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/Headers/ESVideoPhone.h
@@ -4,7 +4,7 @@
//
//  Created by maygion on 2019/3/26.
//  Copyright © 2019 eTouchSky. All rights reserved.
//  SDK版本号:1.1.0
//  SDK版本号:1.0.0  测试版1
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/Info.plist
Binary files differ
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/_CodeSignature/CodeDirectory
Binary files differ
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements
Binary files differ
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements-1
Binary files differ
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/_CodeSignature/CodeResources
@@ -4,10 +4,6 @@
<dict>
    <key>files</key>
    <dict>
        <key>.DS_Store</key>
        <data>
        Y/zzZVahlzqsXsKRy9ythZX/tmM=
        </data>
        <key>Headers/ESError.h</key>
        <data>
        6x23lohs1gRaX2F7raZcezxZt4A=
@@ -18,7 +14,7 @@
        </data>
        <key>Info.plist</key>
        <data>
        YgFQhxxTQ5/xhKsrQd4C5NGn22w=
        pac6jrrTIT3Ur/3XHh3CoCOUlnE=
        </data>
    </dict>
    <key>files2</key>
ESVideoPhoneSDKZigbee/ESVideoPhoneSDk.framework/_CodeSignature/CodeSignature
Binary files differ
xamarin/ESVideoPhoneSDKXamarin/ESVideoPhoneSDKXamarin/ESVideoMonitorViewController.m
@@ -120,7 +120,7 @@
    UIView *TopView =  [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, APP_TOP_BAR_HEIGHT)];
    TopView.backgroundColor = HEXCOLORA(0xF9F9F9,1.0);
    [TopView addSubview:self.backButton];
    [TopView addSubview:self.moreButton];
//    [TopView addSubview:self.moreButton];
    [self.view addSubview:TopView];
    TopView.layer.shadowColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.25].CGColor;
    TopView.layer.shadowOffset = CGSizeMake(0,0.5);
@@ -445,12 +445,12 @@
        return;
    }
    //初始化视频采集Capture
    [self requestAccessForAVMediaType:AVMediaTypeVideo];
    if (isAccessVideo) {
        if(![_es initVideoCaptureSession]){
            NSLog(@"VideoCaptureSession 初始化失败");
        }
    }
//    [self requestAccessForAVMediaType:AVMediaTypeVideo];
//    if (isAccessVideo) {
//        if(![_es initVideoCaptureSession]){
//            NSLog(@"VideoCaptureSession 初始化失败");
//        }
//    }
    //初始化AudioSession
    _sessionHelper = [[AudioSessionHelper alloc]init];
    [_sessionHelper setAudioSession];
@@ -512,7 +512,12 @@
    //在viewDidLoad中 调用requestAccessForAVMediaType: 是为了节约初始化的时间
    //在viewDidAppear中调用requestAccessForAVMediaType: 是为了弹出提示打开权限的Alert
    //测试的时候发现如下情况:如果只把授权方法放到ViewDidAppear方法中处理,如果没有授权在初始化采集器时会失败。同样AlertView会因为View没有didLoad而导致present不出来
    if (!isAccessVideo || !isAccessAudio) {
//    if (!isAccessVideo || !isAccessAudio) {
//        [self requestAccessForAVMedia];
//    }
    if (!isAccessAudio) {
        [self requestAccessForAVMedia];
    }
}
@@ -831,30 +836,37 @@
    
    // 这里是考虑到用户没有授权,之后通过AlertAction跳转到设置页面授权后再回到APP时做的重新检测
    //跳转到设置页面,授权后返回页面,继续初始化采集器
    if (isAccessAudio && isAccessVideo) {
        return;
    }
    if (isAccessVideo && !isAccessAudio) {
    if(!isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
        if (isAccessAudio) {
            [_es initAudioCaptureSession];
        }
    }else if (!isAccessVideo && isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
        if (isAccessVideo) {
            [_es initVideoCaptureSession];
        }
    }else if (!isAccessVideo && !isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
        if (isAccessAudio) {
            [_es initAudioCaptureSession];
        }
        if (isAccessVideo) {
            [_es initVideoCaptureSession];
        }
    }
//    if (isAccessAudio && isAccessVideo) {
//        return;
//    }
//    if (isAccessVideo && !isAccessAudio) {
//        [self requestAccessForAVMediaType:AVMediaTypeAudio];
//        if (isAccessAudio) {
//            [_es initAudioCaptureSession];
//        }
//    }else if (!isAccessVideo && isAccessAudio){
////        [self requestAccessForAVMediaType:AVMediaTypeVideo];
////        if (isAccessVideo) {
////            [_es initVideoCaptureSession];
////        }
//
//    }else if (!isAccessVideo && !isAccessAudio){
//        [self requestAccessForAVMediaType:AVMediaTypeAudio];
////        [self requestAccessForAVMediaType:AVMediaTypeVideo];
//        if (isAccessAudio) {
//            [_es initAudioCaptureSession];
//        }
////        if (isAccessVideo) {
////            [_es initVideoCaptureSession];
////        }
//    }
}
- (void)willEnterBackground:(NSNotification *)notification {
    isBackGround = YES;
@@ -865,9 +877,9 @@
    if (!isAccessAudio) {
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
    }
    if (!isAccessVideo) {
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
    }
//    if (!isAccessVideo) {
////        [self requestAccessForAVMediaType:AVMediaTypeVideo];
//    }
    if (!iSAudioNotDetermined && iSVideoNotDetermined){
        [self creatAlertViewWith:@"授权请求" message:@"麦克风没有授权,请在设置中开启权限,否则将影响通讯功能。" cancel:@"确定"];
    }else if(iSAudioNotDetermined && !iSVideoNotDetermined){
xamarin/ESVideoPhoneSDKXamarin/ESVideoPhoneSDKXamarin/ESvideoVideoIntercomViewController.m
@@ -137,7 +137,7 @@
    UIView *TopView =  [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, APP_TOP_BAR_HEIGHT)];
    TopView.backgroundColor = HEXCOLORA(0xF9F9F9,1.0);
    //    [TopView addSubview:self.backButton];
    [TopView addSubview:self.moreButton];
//    [TopView addSubview:self.moreButton];
    [self.view addSubview:TopView];
    TopView.layer.shadowColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.25].CGColor;
    TopView.layer.shadowOffset = CGSizeMake(0,0.5);
@@ -632,12 +632,12 @@
        return;
    }
    //初始化视频采集Capture
    [self requestAccessForAVMediaType:AVMediaTypeVideo];
    if (isAccessVideo) {
        if(![_es initVideoCaptureSession]){
            NSLog(@"VideoCaptureSession 初始化失败");
        }
    }
//    [self requestAccessForAVMediaType:AVMediaTypeVideo];
//    if (isAccessVideo) {
//        if(![_es initVideoCaptureSession]){
//            NSLog(@"VideoCaptureSession 初始化失败");
//        }
//    }
    //初始化AudioSession
    _sessionHelper = [[AudioSessionHelper alloc]init];
    [_sessionHelper setAudioSession];
@@ -720,7 +720,11 @@
    //在viewDidLoad中 调用requestAccessForAVMediaType: 是为了节约初始化的时间
    //在viewDidAppear中调用requestAccessForAVMediaType: 是为了弹出提示打开权限的Alert
    //测试的时候发现如下情况:如果只把授权方法放到ViewDidAppear方法中处理,如果没有授权在初始化采集器时会失败。同样AlertView会因为View没有didLoad而导致present不出来
    if (!isAccessVideo || !isAccessAudio) {
//    if (!isAccessVideo || !isAccessAudio) {
//        [self requestAccessForAVMedia];
//    }
//
    if (!isAccessAudio) {
        [self requestAccessForAVMedia];
    }
}
@@ -1021,30 +1025,37 @@
    
    // 这里是考虑到用户没有授权,之后通过AlertAction跳转到设置页面授权后再回到APP时做的重新检测
    //跳转到设置页面,授权后返回页面,继续初始化采集器
    if (isAccessAudio && isAccessVideo) {
        return;
    }
    if (isAccessVideo && !isAccessAudio) {
    if(!isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
        if (isAccessAudio) {
            [_es initAudioCaptureSession];
        }
    }else if (!isAccessVideo && isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
        if (isAccessVideo) {
            [_es initVideoCaptureSession];
        }
    }else if (!isAccessVideo && !isAccessAudio){
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
        if (isAccessAudio) {
            [_es initAudioCaptureSession];
        }
        if (isAccessVideo) {
            [_es initVideoCaptureSession];
        }
    }
//    if (isAccessAudio && isAccessVideo) {
//        return;
//    }
//    if (isAccessVideo && !isAccessAudio) {
//        [self requestAccessForAVMediaType:AVMediaTypeAudio];
//        if (isAccessAudio) {
//            [_es initAudioCaptureSession];
//        }
//    }else if (!isAccessVideo && isAccessAudio){
////        [self requestAccessForAVMediaType:AVMediaTypeVideo];
////        if (isAccessVideo) {
////            [_es initVideoCaptureSession];
////        }
//
//    }else if (!isAccessVideo && !isAccessAudio){
//        [self requestAccessForAVMediaType:AVMediaTypeAudio];
////        [self requestAccessForAVMediaType:AVMediaTypeVideo];
//        if (isAccessAudio) {
//            [_es initAudioCaptureSession];
//        }
////        if (isAccessVideo) {
////            [_es initVideoCaptureSession];
////        }
//    }
}
- (void)willEnterBackground:(NSNotification *)notification {
    isBackGround = YES;
@@ -1055,9 +1066,9 @@
    if (!isAccessAudio) {
        [self requestAccessForAVMediaType:AVMediaTypeAudio];
    }
    if (!isAccessVideo) {
        [self requestAccessForAVMediaType:AVMediaTypeVideo];
    }
//    if (!isAccessVideo) {
//        [self requestAccessForAVMediaType:AVMediaTypeVideo];
//    }
    if (!iSAudioNotDetermined && iSVideoNotDetermined){
        [self creatAlertViewWith:@"授权请求" message:@"麦克风没有授权,请在设置中开启权限,否则将影响通讯功能。" cancel:@"确定"];
    }else if(iSAudioNotDetermined && !iSVideoNotDetermined){
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/ESVideoPhoneSDk
Binary files differ
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/Headers/ESVideoPhone.h
@@ -4,7 +4,7 @@
//
//  Created by maygion on 2019/3/26.
//  Copyright © 2019 eTouchSky. All rights reserved.
//  SDK版本号:1.1.0
//  SDK版本号:1.0.0  测试版1
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/Info.plist
Binary files differ
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/_CodeSignature/CodeDirectory
Binary files differ
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements
Binary files differ
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/_CodeSignature/CodeRequirements-1
Binary files differ
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/_CodeSignature/CodeResources
@@ -4,10 +4,6 @@
<dict>
    <key>files</key>
    <dict>
        <key>.DS_Store</key>
        <data>
        Y/zzZVahlzqsXsKRy9ythZX/tmM=
        </data>
        <key>Headers/ESError.h</key>
        <data>
        6x23lohs1gRaX2F7raZcezxZt4A=
@@ -18,7 +14,7 @@
        </data>
        <key>Info.plist</key>
        <data>
        YgFQhxxTQ5/xhKsrQd4C5NGn22w=
        pac6jrrTIT3Ur/3XHh3CoCOUlnE=
        </data>
    </dict>
    <key>files2</key>
xamarin/ESVideoPhoneSDKXamarin/Extern/ESVideoPhoneSDk.framework/_CodeSignature/CodeSignature
Binary files differ
xamarin/ESVideoPhoneSDKXamarin/README.md
New file
@@ -0,0 +1,6 @@
## 丰林可视对讲
### *****V1.0.2*****
### 1.更新SDK,解决反呼不挂断问题。
xamarin/Shared.IOS.ESVideoPhoneSDK/Library/ESVideoPhoneSDk.a
Binary files differ
xamarin/Shared.IOS.ESVideoPhoneSDK/Library/libESVideoPhoneSDKXamarin.a
Binary files differ
xamarin/Shared.IOS.ESVideoPhoneSDK/Properties/AssemblyInfo.cs
@@ -25,7 +25,7 @@
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.1")]
[assembly: AssemblyVersion("1.0.2")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.