├── .gitignore
├── .travis.yml
├── Example
├── Podfile
├── Tests
│ ├── Tests-Info.plist
│ ├── Tests-Prefix.pch
│ ├── Tests.m
│ └── en.lproj
│ │ └── InfoPlist.strings
├── VTAntiScreenCapture.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── VTAntiScreenCapture-Example.xcscheme
└── VTAntiScreenCapture
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── EncodeVC
│ ├── EncodeVC.h
│ └── EncodeVC.m
│ ├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── SimpleDRMVC
│ ├── SimpleDRMVC.h
│ ├── SimpleDRMVC.m
│ ├── VTSimplePlayer.h
│ ├── VTSimplePlayer.m
│ ├── index.m3u8
│ └── text.mp4
│ ├── VTAntiScreenCapture-Info.plist
│ ├── VTAntiScreenCapture-Prefix.pch
│ ├── VTAppDelegate.h
│ ├── VTAppDelegate.m
│ ├── VTDemoTableVC.h
│ ├── VTDemoTableVC.m
│ ├── en.lproj
│ └── InfoPlist.strings
│ └── main.m
├── LICENSE
├── README.md
├── VTAntiScreenCapture.podspec
├── VTAntiScreenCapture
├── Assets
│ └── .gitkeep
└── Classes
│ ├── .gitkeep
│ ├── UIView+antiCapture.h
│ ├── UIView+antiCapture.m
│ ├── VTMP4Encoder.h
│ ├── VTMP4Encoder.m
│ ├── VTPlayer.h
│ └── VTPlayer.m
└── _Pods.xcodeproj
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata/
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 |
22 | # Bundler
23 | .bundle
24 |
25 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
26 | # Carthage/Checkouts
27 |
28 | Carthage/Build
29 |
30 | # We recommend against adding the Pods directory to your .gitignore. However
31 | # you should judge for yourself, the pros and cons are mentioned at:
32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
33 | #
34 | # Note: if you ignore the Pods directory, make sure to uncomment
35 | # `pod install` in .travis.yml
36 | #
37 | # Pods/
38 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # references:
2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/
3 | # * https://github.com/supermarin/xcpretty#usage
4 |
5 | osx_image: xcode7.3
6 | language: objective-c
7 | # cache: cocoapods
8 | # podfile: Example/Podfile
9 | # before_install:
10 | # - gem install cocoapods # Since Travis is not always on latest version
11 | # - pod install --project-directory=Example
12 | script:
13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/VTAntiScreenCapture.xcworkspace -scheme VTAntiScreenCapture-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty
14 | - pod lib lint
15 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | use_frameworks!
2 |
3 | platform :ios, '8.0'
4 |
5 | target 'VTAntiScreenCapture_Example' do
6 | pod 'VTAntiScreenCapture', :path => '../'
7 | pod 'GCDWebServer'
8 | pod 'AFNetworking'
9 | target 'VTAntiScreenCapture_Tests' do
10 | inherit! :search_paths
11 |
12 |
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/Example/Tests/Tests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Example/Tests/Tests-Prefix.pch:
--------------------------------------------------------------------------------
1 | // The contents of this file are implicitly included at the beginning of every test case source file.
2 |
3 | #ifdef __OBJC__
4 |
5 |
6 |
7 | #endif
8 |
--------------------------------------------------------------------------------
/Example/Tests/Tests.m:
--------------------------------------------------------------------------------
1 | //
2 | // VTAntiScreenCaptureTests.m
3 | // VTAntiScreenCaptureTests
4 | //
5 | // Created by mightyme@qq.com on 12/31/2018.
6 | // Copyright (c) 2018 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | @import XCTest;
10 |
11 | @interface Tests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation Tests
16 |
17 | - (void)setUp
18 | {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown
24 | {
25 | // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | [super tearDown];
27 | }
28 |
29 | - (void)testExample
30 | {
31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32 | }
33 |
34 | @end
35 |
36 |
--------------------------------------------------------------------------------
/Example/Tests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 035782A6E0D2DFADCE61443A /* Pods_VTAntiScreenCapture_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E3777863D15BEADD3C31CF4D /* Pods_VTAntiScreenCapture_Example.framework */; };
11 | 584291969AE9729FDE0EABC9 /* Pods_VTAntiScreenCapture_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C360D7C6400C52561405A303 /* Pods_VTAntiScreenCapture_Tests.framework */; };
12 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
13 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; };
14 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
15 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; };
16 | 6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; };
17 | 6003F59E195388D20070C39A /* VTAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* VTAppDelegate.m */; };
18 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; };
19 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; };
20 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
21 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
22 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; };
23 | 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; };
24 | 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; };
25 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };
26 | B519F31821DA2226008C7F6B /* text.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = B519F31621DA2226008C7F6B /* text.mp4 */; };
27 | B519F31921DA2226008C7F6B /* SimpleDRMVC.m in Sources */ = {isa = PBXBuildFile; fileRef = B519F31721DA2226008C7F6B /* SimpleDRMVC.m */; };
28 | B519F31C21DA2264008C7F6B /* VTDemoTableVC.m in Sources */ = {isa = PBXBuildFile; fileRef = B519F31B21DA2264008C7F6B /* VTDemoTableVC.m */; };
29 | B519F31F21DA2346008C7F6B /* VTSimplePlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = B519F31E21DA2346008C7F6B /* VTSimplePlayer.m */; };
30 | B519F32F21DB0C2B008C7F6B /* EncodeVC.m in Sources */ = {isa = PBXBuildFile; fileRef = B519F32E21DB0C2B008C7F6B /* EncodeVC.m */; };
31 | /* End PBXBuildFile section */
32 |
33 | /* Begin PBXContainerItemProxy section */
34 | 6003F5B3195388D20070C39A /* PBXContainerItemProxy */ = {
35 | isa = PBXContainerItemProxy;
36 | containerPortal = 6003F582195388D10070C39A /* Project object */;
37 | proxyType = 1;
38 | remoteGlobalIDString = 6003F589195388D20070C39A;
39 | remoteInfo = VTAntiScreenCapture;
40 | };
41 | /* End PBXContainerItemProxy section */
42 |
43 | /* Begin PBXFileReference section */
44 | 1C18C4D37554D27CEF37EBC4 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; };
45 | 2E96A21A8EDD1CD7A63226C2 /* VTAntiScreenCapture.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = VTAntiScreenCapture.podspec; path = ../VTAntiScreenCapture.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
46 | 3C5CD6229265801AC1EF7A49 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; };
47 | 6003F58A195388D20070C39A /* VTAntiScreenCapture_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VTAntiScreenCapture_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
48 | 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
49 | 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
50 | 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
51 | 6003F595195388D20070C39A /* VTAntiScreenCapture-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "VTAntiScreenCapture-Info.plist"; sourceTree = ""; };
52 | 6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
53 | 6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
54 | 6003F59B195388D20070C39A /* VTAntiScreenCapture-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VTAntiScreenCapture-Prefix.pch"; sourceTree = ""; };
55 | 6003F59C195388D20070C39A /* VTAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VTAppDelegate.h; sourceTree = ""; };
56 | 6003F59D195388D20070C39A /* VTAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VTAppDelegate.m; sourceTree = ""; };
57 | 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
58 | 6003F5AE195388D20070C39A /* VTAntiScreenCapture_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VTAntiScreenCapture_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
59 | 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
60 | 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = ""; };
61 | 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
62 | 6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = ""; };
63 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = ""; };
64 | 70E35D6D10B70079BA206F40 /* Pods-VTAntiScreenCapture_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VTAntiScreenCapture_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VTAntiScreenCapture_Example/Pods-VTAntiScreenCapture_Example.debug.xcconfig"; sourceTree = ""; };
65 | 71719F9E1E33DC2100824A3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
66 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = ""; };
67 | B4AB297A5A8C057C83A06D72 /* Pods-VTAntiScreenCapture_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VTAntiScreenCapture_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-VTAntiScreenCapture_Tests/Pods-VTAntiScreenCapture_Tests.release.xcconfig"; sourceTree = ""; };
68 | B519F31521DA2226008C7F6B /* SimpleDRMVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleDRMVC.h; sourceTree = ""; };
69 | B519F31621DA2226008C7F6B /* text.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = text.mp4; sourceTree = ""; };
70 | B519F31721DA2226008C7F6B /* SimpleDRMVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimpleDRMVC.m; sourceTree = ""; };
71 | B519F31A21DA2264008C7F6B /* VTDemoTableVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VTDemoTableVC.h; sourceTree = ""; };
72 | B519F31B21DA2264008C7F6B /* VTDemoTableVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VTDemoTableVC.m; sourceTree = ""; };
73 | B519F31D21DA2346008C7F6B /* VTSimplePlayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VTSimplePlayer.h; sourceTree = ""; };
74 | B519F31E21DA2346008C7F6B /* VTSimplePlayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VTSimplePlayer.m; sourceTree = ""; };
75 | B519F32D21DB0C2B008C7F6B /* EncodeVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EncodeVC.h; sourceTree = ""; };
76 | B519F32E21DB0C2B008C7F6B /* EncodeVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EncodeVC.m; sourceTree = ""; };
77 | C360D7C6400C52561405A303 /* Pods_VTAntiScreenCapture_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VTAntiScreenCapture_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
78 | DEB169BF241381E4A7CF74EB /* Pods-VTAntiScreenCapture_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VTAntiScreenCapture_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-VTAntiScreenCapture_Example/Pods-VTAntiScreenCapture_Example.release.xcconfig"; sourceTree = ""; };
79 | E3777863D15BEADD3C31CF4D /* Pods_VTAntiScreenCapture_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VTAntiScreenCapture_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
80 | F54844A1F1585A881352257A /* Pods-VTAntiScreenCapture_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VTAntiScreenCapture_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VTAntiScreenCapture_Tests/Pods-VTAntiScreenCapture_Tests.debug.xcconfig"; sourceTree = ""; };
81 | /* End PBXFileReference section */
82 |
83 | /* Begin PBXFrameworksBuildPhase section */
84 | 6003F587195388D20070C39A /* Frameworks */ = {
85 | isa = PBXFrameworksBuildPhase;
86 | buildActionMask = 2147483647;
87 | files = (
88 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,
89 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */,
90 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */,
91 | 035782A6E0D2DFADCE61443A /* Pods_VTAntiScreenCapture_Example.framework in Frameworks */,
92 | );
93 | runOnlyForDeploymentPostprocessing = 0;
94 | };
95 | 6003F5AB195388D20070C39A /* Frameworks */ = {
96 | isa = PBXFrameworksBuildPhase;
97 | buildActionMask = 2147483647;
98 | files = (
99 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,
100 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,
101 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */,
102 | 584291969AE9729FDE0EABC9 /* Pods_VTAntiScreenCapture_Tests.framework in Frameworks */,
103 | );
104 | runOnlyForDeploymentPostprocessing = 0;
105 | };
106 | /* End PBXFrameworksBuildPhase section */
107 |
108 | /* Begin PBXGroup section */
109 | 6003F581195388D10070C39A = {
110 | isa = PBXGroup;
111 | children = (
112 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */,
113 | 6003F593195388D20070C39A /* Example for VTAntiScreenCapture */,
114 | 6003F5B5195388D20070C39A /* Tests */,
115 | 6003F58C195388D20070C39A /* Frameworks */,
116 | 6003F58B195388D20070C39A /* Products */,
117 | D7D1DE4D7180B6B8AF359FFC /* Pods */,
118 | );
119 | sourceTree = "";
120 | };
121 | 6003F58B195388D20070C39A /* Products */ = {
122 | isa = PBXGroup;
123 | children = (
124 | 6003F58A195388D20070C39A /* VTAntiScreenCapture_Example.app */,
125 | 6003F5AE195388D20070C39A /* VTAntiScreenCapture_Tests.xctest */,
126 | );
127 | name = Products;
128 | sourceTree = "";
129 | };
130 | 6003F58C195388D20070C39A /* Frameworks */ = {
131 | isa = PBXGroup;
132 | children = (
133 | 6003F58D195388D20070C39A /* Foundation.framework */,
134 | 6003F58F195388D20070C39A /* CoreGraphics.framework */,
135 | 6003F591195388D20070C39A /* UIKit.framework */,
136 | 6003F5AF195388D20070C39A /* XCTest.framework */,
137 | E3777863D15BEADD3C31CF4D /* Pods_VTAntiScreenCapture_Example.framework */,
138 | C360D7C6400C52561405A303 /* Pods_VTAntiScreenCapture_Tests.framework */,
139 | );
140 | name = Frameworks;
141 | sourceTree = "";
142 | };
143 | 6003F593195388D20070C39A /* Example for VTAntiScreenCapture */ = {
144 | isa = PBXGroup;
145 | children = (
146 | B519F32C21DB0C16008C7F6B /* EncodeVC */,
147 | B519F31421DA2226008C7F6B /* SimpleDRMVC */,
148 | 6003F59C195388D20070C39A /* VTAppDelegate.h */,
149 | 6003F59D195388D20070C39A /* VTAppDelegate.m */,
150 | B519F31A21DA2264008C7F6B /* VTDemoTableVC.h */,
151 | B519F31B21DA2264008C7F6B /* VTDemoTableVC.m */,
152 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */,
153 | 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */,
154 | 6003F5A8195388D20070C39A /* Images.xcassets */,
155 | 6003F594195388D20070C39A /* Supporting Files */,
156 | );
157 | name = "Example for VTAntiScreenCapture";
158 | path = VTAntiScreenCapture;
159 | sourceTree = "";
160 | };
161 | 6003F594195388D20070C39A /* Supporting Files */ = {
162 | isa = PBXGroup;
163 | children = (
164 | 6003F595195388D20070C39A /* VTAntiScreenCapture-Info.plist */,
165 | 6003F596195388D20070C39A /* InfoPlist.strings */,
166 | 6003F599195388D20070C39A /* main.m */,
167 | 6003F59B195388D20070C39A /* VTAntiScreenCapture-Prefix.pch */,
168 | );
169 | name = "Supporting Files";
170 | sourceTree = "";
171 | };
172 | 6003F5B5195388D20070C39A /* Tests */ = {
173 | isa = PBXGroup;
174 | children = (
175 | 6003F5BB195388D20070C39A /* Tests.m */,
176 | 6003F5B6195388D20070C39A /* Supporting Files */,
177 | );
178 | path = Tests;
179 | sourceTree = "";
180 | };
181 | 6003F5B6195388D20070C39A /* Supporting Files */ = {
182 | isa = PBXGroup;
183 | children = (
184 | 6003F5B7195388D20070C39A /* Tests-Info.plist */,
185 | 6003F5B8195388D20070C39A /* InfoPlist.strings */,
186 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */,
187 | );
188 | name = "Supporting Files";
189 | sourceTree = "";
190 | };
191 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = {
192 | isa = PBXGroup;
193 | children = (
194 | 2E96A21A8EDD1CD7A63226C2 /* VTAntiScreenCapture.podspec */,
195 | 1C18C4D37554D27CEF37EBC4 /* README.md */,
196 | 3C5CD6229265801AC1EF7A49 /* LICENSE */,
197 | );
198 | name = "Podspec Metadata";
199 | sourceTree = "";
200 | };
201 | B519F31421DA2226008C7F6B /* SimpleDRMVC */ = {
202 | isa = PBXGroup;
203 | children = (
204 | B519F31621DA2226008C7F6B /* text.mp4 */,
205 | B519F31521DA2226008C7F6B /* SimpleDRMVC.h */,
206 | B519F31721DA2226008C7F6B /* SimpleDRMVC.m */,
207 | B519F31D21DA2346008C7F6B /* VTSimplePlayer.h */,
208 | B519F31E21DA2346008C7F6B /* VTSimplePlayer.m */,
209 | );
210 | path = SimpleDRMVC;
211 | sourceTree = "";
212 | };
213 | B519F32C21DB0C16008C7F6B /* EncodeVC */ = {
214 | isa = PBXGroup;
215 | children = (
216 | B519F32D21DB0C2B008C7F6B /* EncodeVC.h */,
217 | B519F32E21DB0C2B008C7F6B /* EncodeVC.m */,
218 | );
219 | path = EncodeVC;
220 | sourceTree = "";
221 | };
222 | D7D1DE4D7180B6B8AF359FFC /* Pods */ = {
223 | isa = PBXGroup;
224 | children = (
225 | 70E35D6D10B70079BA206F40 /* Pods-VTAntiScreenCapture_Example.debug.xcconfig */,
226 | DEB169BF241381E4A7CF74EB /* Pods-VTAntiScreenCapture_Example.release.xcconfig */,
227 | F54844A1F1585A881352257A /* Pods-VTAntiScreenCapture_Tests.debug.xcconfig */,
228 | B4AB297A5A8C057C83A06D72 /* Pods-VTAntiScreenCapture_Tests.release.xcconfig */,
229 | );
230 | name = Pods;
231 | sourceTree = "";
232 | };
233 | /* End PBXGroup section */
234 |
235 | /* Begin PBXNativeTarget section */
236 | 6003F589195388D20070C39A /* VTAntiScreenCapture_Example */ = {
237 | isa = PBXNativeTarget;
238 | buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "VTAntiScreenCapture_Example" */;
239 | buildPhases = (
240 | 8CDB88E1DBD6869D915B63AC /* [CP] Check Pods Manifest.lock */,
241 | 6003F586195388D20070C39A /* Sources */,
242 | 6003F587195388D20070C39A /* Frameworks */,
243 | 6003F588195388D20070C39A /* Resources */,
244 | F15D71A19ACFA6501D486511 /* [CP] Embed Pods Frameworks */,
245 | );
246 | buildRules = (
247 | );
248 | dependencies = (
249 | );
250 | name = VTAntiScreenCapture_Example;
251 | productName = VTAntiScreenCapture;
252 | productReference = 6003F58A195388D20070C39A /* VTAntiScreenCapture_Example.app */;
253 | productType = "com.apple.product-type.application";
254 | };
255 | 6003F5AD195388D20070C39A /* VTAntiScreenCapture_Tests */ = {
256 | isa = PBXNativeTarget;
257 | buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "VTAntiScreenCapture_Tests" */;
258 | buildPhases = (
259 | DF706BBACABE40E03F9F5EC7 /* [CP] Check Pods Manifest.lock */,
260 | 6003F5AA195388D20070C39A /* Sources */,
261 | 6003F5AB195388D20070C39A /* Frameworks */,
262 | 6003F5AC195388D20070C39A /* Resources */,
263 | );
264 | buildRules = (
265 | );
266 | dependencies = (
267 | 6003F5B4195388D20070C39A /* PBXTargetDependency */,
268 | );
269 | name = VTAntiScreenCapture_Tests;
270 | productName = VTAntiScreenCaptureTests;
271 | productReference = 6003F5AE195388D20070C39A /* VTAntiScreenCapture_Tests.xctest */;
272 | productType = "com.apple.product-type.bundle.unit-test";
273 | };
274 | /* End PBXNativeTarget section */
275 |
276 | /* Begin PBXProject section */
277 | 6003F582195388D10070C39A /* Project object */ = {
278 | isa = PBXProject;
279 | attributes = {
280 | CLASSPREFIX = VT;
281 | LastUpgradeCheck = 0720;
282 | ORGANIZATIONNAME = "yuweishan@126.com";
283 | TargetAttributes = {
284 | 6003F589195388D20070C39A = {
285 | DevelopmentTeam = 664M9NYFXA;
286 | ProvisioningStyle = Automatic;
287 | };
288 | 6003F5AD195388D20070C39A = {
289 | TestTargetID = 6003F589195388D20070C39A;
290 | };
291 | };
292 | };
293 | buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "VTAntiScreenCapture" */;
294 | compatibilityVersion = "Xcode 3.2";
295 | developmentRegion = English;
296 | hasScannedForEncodings = 0;
297 | knownRegions = (
298 | en,
299 | Base,
300 | );
301 | mainGroup = 6003F581195388D10070C39A;
302 | productRefGroup = 6003F58B195388D20070C39A /* Products */;
303 | projectDirPath = "";
304 | projectRoot = "";
305 | targets = (
306 | 6003F589195388D20070C39A /* VTAntiScreenCapture_Example */,
307 | 6003F5AD195388D20070C39A /* VTAntiScreenCapture_Tests */,
308 | );
309 | };
310 | /* End PBXProject section */
311 |
312 | /* Begin PBXResourcesBuildPhase section */
313 | 6003F588195388D20070C39A /* Resources */ = {
314 | isa = PBXResourcesBuildPhase;
315 | buildActionMask = 2147483647;
316 | files = (
317 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */,
318 | 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */,
319 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */,
320 | B519F31821DA2226008C7F6B /* text.mp4 in Resources */,
321 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */,
322 | );
323 | runOnlyForDeploymentPostprocessing = 0;
324 | };
325 | 6003F5AC195388D20070C39A /* Resources */ = {
326 | isa = PBXResourcesBuildPhase;
327 | buildActionMask = 2147483647;
328 | files = (
329 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */,
330 | );
331 | runOnlyForDeploymentPostprocessing = 0;
332 | };
333 | /* End PBXResourcesBuildPhase section */
334 |
335 | /* Begin PBXShellScriptBuildPhase section */
336 | 8CDB88E1DBD6869D915B63AC /* [CP] Check Pods Manifest.lock */ = {
337 | isa = PBXShellScriptBuildPhase;
338 | buildActionMask = 2147483647;
339 | files = (
340 | );
341 | inputFileListPaths = (
342 | );
343 | inputPaths = (
344 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
345 | "${PODS_ROOT}/Manifest.lock",
346 | );
347 | name = "[CP] Check Pods Manifest.lock";
348 | outputFileListPaths = (
349 | );
350 | outputPaths = (
351 | "$(DERIVED_FILE_DIR)/Pods-VTAntiScreenCapture_Example-checkManifestLockResult.txt",
352 | );
353 | runOnlyForDeploymentPostprocessing = 0;
354 | shellPath = /bin/sh;
355 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
356 | showEnvVarsInLog = 0;
357 | };
358 | DF706BBACABE40E03F9F5EC7 /* [CP] Check Pods Manifest.lock */ = {
359 | isa = PBXShellScriptBuildPhase;
360 | buildActionMask = 2147483647;
361 | files = (
362 | );
363 | inputFileListPaths = (
364 | );
365 | inputPaths = (
366 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
367 | "${PODS_ROOT}/Manifest.lock",
368 | );
369 | name = "[CP] Check Pods Manifest.lock";
370 | outputFileListPaths = (
371 | );
372 | outputPaths = (
373 | "$(DERIVED_FILE_DIR)/Pods-VTAntiScreenCapture_Tests-checkManifestLockResult.txt",
374 | );
375 | runOnlyForDeploymentPostprocessing = 0;
376 | shellPath = /bin/sh;
377 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
378 | showEnvVarsInLog = 0;
379 | };
380 | F15D71A19ACFA6501D486511 /* [CP] Embed Pods Frameworks */ = {
381 | isa = PBXShellScriptBuildPhase;
382 | buildActionMask = 2147483647;
383 | files = (
384 | );
385 | inputFileListPaths = (
386 | );
387 | inputPaths = (
388 | "${SRCROOT}/Pods/Target Support Files/Pods-VTAntiScreenCapture_Example/Pods-VTAntiScreenCapture_Example-frameworks.sh",
389 | "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
390 | "${BUILT_PRODUCTS_DIR}/GCDWebServer/GCDWebServer.framework",
391 | "${BUILT_PRODUCTS_DIR}/VTAntiScreenCapture/VTAntiScreenCapture.framework",
392 | );
393 | name = "[CP] Embed Pods Frameworks";
394 | outputFileListPaths = (
395 | );
396 | outputPaths = (
397 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework",
398 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GCDWebServer.framework",
399 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/VTAntiScreenCapture.framework",
400 | );
401 | runOnlyForDeploymentPostprocessing = 0;
402 | shellPath = /bin/sh;
403 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-VTAntiScreenCapture_Example/Pods-VTAntiScreenCapture_Example-frameworks.sh\"\n";
404 | showEnvVarsInLog = 0;
405 | };
406 | /* End PBXShellScriptBuildPhase section */
407 |
408 | /* Begin PBXSourcesBuildPhase section */
409 | 6003F586195388D20070C39A /* Sources */ = {
410 | isa = PBXSourcesBuildPhase;
411 | buildActionMask = 2147483647;
412 | files = (
413 | B519F32F21DB0C2B008C7F6B /* EncodeVC.m in Sources */,
414 | 6003F59E195388D20070C39A /* VTAppDelegate.m in Sources */,
415 | B519F31921DA2226008C7F6B /* SimpleDRMVC.m in Sources */,
416 | B519F31C21DA2264008C7F6B /* VTDemoTableVC.m in Sources */,
417 | B519F31F21DA2346008C7F6B /* VTSimplePlayer.m in Sources */,
418 | 6003F59A195388D20070C39A /* main.m in Sources */,
419 | );
420 | runOnlyForDeploymentPostprocessing = 0;
421 | };
422 | 6003F5AA195388D20070C39A /* Sources */ = {
423 | isa = PBXSourcesBuildPhase;
424 | buildActionMask = 2147483647;
425 | files = (
426 | 6003F5BC195388D20070C39A /* Tests.m in Sources */,
427 | );
428 | runOnlyForDeploymentPostprocessing = 0;
429 | };
430 | /* End PBXSourcesBuildPhase section */
431 |
432 | /* Begin PBXTargetDependency section */
433 | 6003F5B4195388D20070C39A /* PBXTargetDependency */ = {
434 | isa = PBXTargetDependency;
435 | target = 6003F589195388D20070C39A /* VTAntiScreenCapture_Example */;
436 | targetProxy = 6003F5B3195388D20070C39A /* PBXContainerItemProxy */;
437 | };
438 | /* End PBXTargetDependency section */
439 |
440 | /* Begin PBXVariantGroup section */
441 | 6003F596195388D20070C39A /* InfoPlist.strings */ = {
442 | isa = PBXVariantGroup;
443 | children = (
444 | 6003F597195388D20070C39A /* en */,
445 | );
446 | name = InfoPlist.strings;
447 | sourceTree = "";
448 | };
449 | 6003F5B8195388D20070C39A /* InfoPlist.strings */ = {
450 | isa = PBXVariantGroup;
451 | children = (
452 | 6003F5B9195388D20070C39A /* en */,
453 | );
454 | name = InfoPlist.strings;
455 | sourceTree = "";
456 | };
457 | 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */ = {
458 | isa = PBXVariantGroup;
459 | children = (
460 | 71719F9E1E33DC2100824A3D /* Base */,
461 | );
462 | name = LaunchScreen.storyboard;
463 | sourceTree = "";
464 | };
465 | /* End PBXVariantGroup section */
466 |
467 | /* Begin XCBuildConfiguration section */
468 | 6003F5BD195388D20070C39A /* Debug */ = {
469 | isa = XCBuildConfiguration;
470 | buildSettings = {
471 | ALWAYS_SEARCH_USER_PATHS = NO;
472 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
473 | CLANG_CXX_LIBRARY = "libc++";
474 | CLANG_ENABLE_MODULES = YES;
475 | CLANG_ENABLE_OBJC_ARC = YES;
476 | CLANG_WARN_BOOL_CONVERSION = YES;
477 | CLANG_WARN_CONSTANT_CONVERSION = YES;
478 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
479 | CLANG_WARN_EMPTY_BODY = YES;
480 | CLANG_WARN_ENUM_CONVERSION = YES;
481 | CLANG_WARN_INT_CONVERSION = YES;
482 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
483 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
484 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
485 | COPY_PHASE_STRIP = NO;
486 | ENABLE_TESTABILITY = YES;
487 | GCC_C_LANGUAGE_STANDARD = gnu99;
488 | GCC_DYNAMIC_NO_PIC = NO;
489 | GCC_OPTIMIZATION_LEVEL = 0;
490 | GCC_PREPROCESSOR_DEFINITIONS = (
491 | "DEBUG=1",
492 | "$(inherited)",
493 | );
494 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
495 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
496 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
497 | GCC_WARN_UNDECLARED_SELECTOR = YES;
498 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
499 | GCC_WARN_UNUSED_FUNCTION = YES;
500 | GCC_WARN_UNUSED_VARIABLE = YES;
501 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
502 | ONLY_ACTIVE_ARCH = YES;
503 | SDKROOT = iphoneos;
504 | TARGETED_DEVICE_FAMILY = "1,2";
505 | };
506 | name = Debug;
507 | };
508 | 6003F5BE195388D20070C39A /* Release */ = {
509 | isa = XCBuildConfiguration;
510 | buildSettings = {
511 | ALWAYS_SEARCH_USER_PATHS = NO;
512 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
513 | CLANG_CXX_LIBRARY = "libc++";
514 | CLANG_ENABLE_MODULES = YES;
515 | CLANG_ENABLE_OBJC_ARC = YES;
516 | CLANG_WARN_BOOL_CONVERSION = YES;
517 | CLANG_WARN_CONSTANT_CONVERSION = YES;
518 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
519 | CLANG_WARN_EMPTY_BODY = YES;
520 | CLANG_WARN_ENUM_CONVERSION = YES;
521 | CLANG_WARN_INT_CONVERSION = YES;
522 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
523 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
524 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
525 | COPY_PHASE_STRIP = YES;
526 | ENABLE_NS_ASSERTIONS = NO;
527 | GCC_C_LANGUAGE_STANDARD = gnu99;
528 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
529 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
530 | GCC_WARN_UNDECLARED_SELECTOR = YES;
531 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
532 | GCC_WARN_UNUSED_FUNCTION = YES;
533 | GCC_WARN_UNUSED_VARIABLE = YES;
534 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
535 | SDKROOT = iphoneos;
536 | TARGETED_DEVICE_FAMILY = "1,2";
537 | VALIDATE_PRODUCT = YES;
538 | };
539 | name = Release;
540 | };
541 | 6003F5C0195388D20070C39A /* Debug */ = {
542 | isa = XCBuildConfiguration;
543 | baseConfigurationReference = 70E35D6D10B70079BA206F40 /* Pods-VTAntiScreenCapture_Example.debug.xcconfig */;
544 | buildSettings = {
545 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
546 | CODE_SIGN_IDENTITY = "iPhone Developer";
547 | CODE_SIGN_STYLE = Automatic;
548 | DEVELOPMENT_TEAM = 664M9NYFXA;
549 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
550 | GCC_PREFIX_HEADER = "VTAntiScreenCapture/VTAntiScreenCapture-Prefix.pch";
551 | INFOPLIST_FILE = "VTAntiScreenCapture/VTAntiScreenCapture-Info.plist";
552 | MODULE_NAME = ExampleApp;
553 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
554 | PRODUCT_NAME = "$(TARGET_NAME)";
555 | PROVISIONING_PROFILE_SPECIFIER = "";
556 | WRAPPER_EXTENSION = app;
557 | };
558 | name = Debug;
559 | };
560 | 6003F5C1195388D20070C39A /* Release */ = {
561 | isa = XCBuildConfiguration;
562 | baseConfigurationReference = DEB169BF241381E4A7CF74EB /* Pods-VTAntiScreenCapture_Example.release.xcconfig */;
563 | buildSettings = {
564 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
565 | CODE_SIGN_IDENTITY = "iPhone Developer";
566 | CODE_SIGN_STYLE = Automatic;
567 | DEVELOPMENT_TEAM = 664M9NYFXA;
568 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
569 | GCC_PREFIX_HEADER = "VTAntiScreenCapture/VTAntiScreenCapture-Prefix.pch";
570 | INFOPLIST_FILE = "VTAntiScreenCapture/VTAntiScreenCapture-Info.plist";
571 | MODULE_NAME = ExampleApp;
572 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
573 | PRODUCT_NAME = "$(TARGET_NAME)";
574 | PROVISIONING_PROFILE_SPECIFIER = "";
575 | WRAPPER_EXTENSION = app;
576 | };
577 | name = Release;
578 | };
579 | 6003F5C3195388D20070C39A /* Debug */ = {
580 | isa = XCBuildConfiguration;
581 | baseConfigurationReference = F54844A1F1585A881352257A /* Pods-VTAntiScreenCapture_Tests.debug.xcconfig */;
582 | buildSettings = {
583 | BUNDLE_LOADER = "$(TEST_HOST)";
584 | FRAMEWORK_SEARCH_PATHS = (
585 | "$(SDKROOT)/Developer/Library/Frameworks",
586 | "$(inherited)",
587 | "$(DEVELOPER_FRAMEWORKS_DIR)",
588 | );
589 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
590 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch";
591 | GCC_PREPROCESSOR_DEFINITIONS = (
592 | "DEBUG=1",
593 | "$(inherited)",
594 | );
595 | INFOPLIST_FILE = "Tests/Tests-Info.plist";
596 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
597 | PRODUCT_NAME = "$(TARGET_NAME)";
598 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VTAntiScreenCapture_Example.app/VTAntiScreenCapture_Example";
599 | WRAPPER_EXTENSION = xctest;
600 | };
601 | name = Debug;
602 | };
603 | 6003F5C4195388D20070C39A /* Release */ = {
604 | isa = XCBuildConfiguration;
605 | baseConfigurationReference = B4AB297A5A8C057C83A06D72 /* Pods-VTAntiScreenCapture_Tests.release.xcconfig */;
606 | buildSettings = {
607 | BUNDLE_LOADER = "$(TEST_HOST)";
608 | FRAMEWORK_SEARCH_PATHS = (
609 | "$(SDKROOT)/Developer/Library/Frameworks",
610 | "$(inherited)",
611 | "$(DEVELOPER_FRAMEWORKS_DIR)",
612 | );
613 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
614 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch";
615 | INFOPLIST_FILE = "Tests/Tests-Info.plist";
616 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
617 | PRODUCT_NAME = "$(TARGET_NAME)";
618 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VTAntiScreenCapture_Example.app/VTAntiScreenCapture_Example";
619 | WRAPPER_EXTENSION = xctest;
620 | };
621 | name = Release;
622 | };
623 | /* End XCBuildConfiguration section */
624 |
625 | /* Begin XCConfigurationList section */
626 | 6003F585195388D10070C39A /* Build configuration list for PBXProject "VTAntiScreenCapture" */ = {
627 | isa = XCConfigurationList;
628 | buildConfigurations = (
629 | 6003F5BD195388D20070C39A /* Debug */,
630 | 6003F5BE195388D20070C39A /* Release */,
631 | );
632 | defaultConfigurationIsVisible = 0;
633 | defaultConfigurationName = Release;
634 | };
635 | 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "VTAntiScreenCapture_Example" */ = {
636 | isa = XCConfigurationList;
637 | buildConfigurations = (
638 | 6003F5C0195388D20070C39A /* Debug */,
639 | 6003F5C1195388D20070C39A /* Release */,
640 | );
641 | defaultConfigurationIsVisible = 0;
642 | defaultConfigurationName = Release;
643 | };
644 | 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "VTAntiScreenCapture_Tests" */ = {
645 | isa = XCConfigurationList;
646 | buildConfigurations = (
647 | 6003F5C3195388D20070C39A /* Debug */,
648 | 6003F5C4195388D20070C39A /* Release */,
649 | );
650 | defaultConfigurationIsVisible = 0;
651 | defaultConfigurationName = Release;
652 | };
653 | /* End XCConfigurationList section */
654 | };
655 | rootObject = 6003F582195388D10070C39A /* Project object */;
656 | }
657 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture.xcodeproj/xcshareddata/xcschemes/VTAntiScreenCapture-Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
189 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/EncodeVC/EncodeVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // EncodeVC.h
3 | // VTAntiScreenCapture_Example
4 | //
5 | // Created by Vincent on 2019/1/1.
6 | // Copyright © 2019 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface EncodeVC : UIViewController
14 |
15 | @property (nonatomic, strong) IBOutlet UILabel *label;
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/EncodeVC/EncodeVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // EncodeVC.m
3 | // VTAntiScreenCapture_Example
4 | //
5 | // Created by Vincent on 2019/1/1.
6 | // Copyright © 2019 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | #import "EncodeVC.h"
10 | #import
11 |
12 | @implementation EncodeVC
13 |
14 | - (IBAction)onCreateVideo:(id)sender {
15 | [VTMP4Encoder encodeViewToMP4:self.label completion:^(NSData *data) {
16 | NSLog(@"data: %@", data);
17 | }];
18 | }
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/SimpleDRMVC/SimpleDRMVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // SimpleDRMVC.h
3 | // VCAntiScreenCapture_Example
4 | //
5 | // Created by Vincent on 2018/12/31.
6 | // Copyright © 2018 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface SimpleDRMVC : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/SimpleDRMVC/SimpleDRMVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // SimpleDRMVC.m
3 | // VCAntiScreenCapture_Example
4 | //
5 | // Created by Vincent on 2018/12/31.
6 | // Copyright © 2018 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | #import "SimpleDRMVC.h"
10 | #import "GCDWebServer.h"
11 | #import "GCDWebServerFileResponse.h"
12 | #import "VTSimplePlayer.h"
13 | #import "AFNetworking.h"
14 |
15 | @interface SimpleDRMVC ()
16 |
17 | @property (nonatomic, weak) IBOutlet UIView *labelContainer;
18 | @property (nonatomic, strong) GCDWebServer *webServer;
19 | @property (nonatomic, strong) VTSimplePlayer *player;
20 |
21 | @end
22 |
23 | @implementation SimpleDRMVC
24 |
25 | - (void)viewDidLoad {
26 | [super viewDidLoad];
27 | // Do any additional setup after loading the view.
28 | // Create server
29 | _webServer = [[GCDWebServer alloc] init];
30 |
31 | NSString *dir=[NSHomeDirectory() stringByAppendingPathComponent:@"tmp/www/"];
32 | [[NSFileManager defaultManager] createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil];
33 | // NSString *path = [[NSBundle mainBundle] pathForResource:@"test_output" ofType:@"mp4"];
34 | NSString *path = [[NSBundle mainBundle] pathForResource:@"text" ofType:@"mp4"];
35 | NSString *toPath = [dir stringByAppendingPathComponent:@"text"];
36 | if ([[NSFileManager defaultManager] fileExistsAtPath:toPath]) {
37 | [[NSFileManager defaultManager] removeItemAtPath:toPath error:nil];
38 | }
39 | [[NSFileManager defaultManager] copyItemAtPath:path toPath:toPath error:nil];
40 |
41 | [_webServer addGETHandlerForBasePath:@"/" directoryPath:dir indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
42 | [_webServer startWithPort:8989 bonjourName:nil];
43 |
44 | _player = [VTSimplePlayer new];
45 | __weak typeof(self) weakSelf = self;
46 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
47 | // [weakSelf.player playURL:@"http://localhost:8989/text.mp4" inView:self.labelContainer];
48 | [weakSelf.player playURL:@"jedi://text.m3u8" inView:self.labelContainer];
49 | });
50 |
51 | return;
52 | }
53 |
54 | //- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
55 | // [self getMP4File];
56 | //}
57 |
58 | - (void)getMP4File {
59 | NSString *url = [NSString stringWithFormat:@"http://localhost:%@/text.mp4", @(8989)];
60 |
61 | NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
62 | NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
63 | AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
64 |
65 | NSURLSessionDownloadTask *_downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
66 |
67 | } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
68 |
69 | NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
70 | NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
71 | return [NSURL fileURLWithPath:path];
72 |
73 | } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
74 | //设置下载完成操作
75 | // filePath就是你下载文件的位置,你可以解压,也可以直接拿来使用
76 |
77 | NSString *imgFilePath = [filePath path];// 将NSURL转成NSString
78 | NSData *data = [[NSData alloc]initWithContentsOfFile:imgFilePath];
79 | NSLog(@"%@", data);
80 | }];
81 | [_downloadTask resume];
82 | }
83 |
84 | - (void)dealloc {
85 | [_webServer stop];
86 | _webServer = nil;
87 | }
88 |
89 |
90 | @end
91 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/SimpleDRMVC/VTSimplePlayer.h:
--------------------------------------------------------------------------------
1 | //
2 | // VTSimplePlayer.h
3 | // VTAntiScreenCapture_Example
4 | //
5 | // Created by Vincent on 2018/12/31.
6 | // Copyright © 2018 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface VTSimplePlayer : NSObject
12 |
13 | - (void)playURL:(NSString *)url inView:(UIView *)container;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/SimpleDRMVC/VTSimplePlayer.m:
--------------------------------------------------------------------------------
1 | //
2 | // VTSimplePlayer.m
3 | // VTAntiScreenCapture_Example
4 | //
5 | // Created by Vincent on 2018/12/31.
6 | // Copyright © 2018 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | #import "VTSimplePlayer.h"
10 | #import
11 |
12 | #pragma mark - VTSimpleResourceLoaderDelegate
13 |
14 | @interface VTSimpleResourceLoaderDelegate : NSObject
15 |
16 | @end
17 |
18 | @implementation VTSimpleResourceLoaderDelegate
19 |
20 | -(BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest{
21 |
22 | NSString *url = loadingRequest.request.URL.absoluteString;
23 | if ([url isEqualToString:@"jedi://text.m3u8"]) {
24 | NSData *data = [[self gen_m3u8] dataUsingEncoding:NSUTF8StringEncoding];
25 | [loadingRequest.dataRequest respondWithData:data];
26 | [loadingRequest finishLoading];
27 | }
28 | else if([url isEqualToString:@"jedi://text.key"]) {
29 | NSMutableData *data = [NSMutableData dataWithLength:16];
30 | [data resetBytesInRange:NSMakeRange(0, [data length])];
31 | [loadingRequest.dataRequest respondWithData:data];
32 | [loadingRequest finishLoading];
33 | }
34 |
35 | return YES;
36 | }
37 |
38 | - (NSString *)gen_m3u8 {
39 | NSString *format = @"#EXTM3U\n\
40 | #EXT-X-PLAYLIST-TYPE:VOD\n\
41 | #EXT-X-VERSION:5\n\
42 | #EXT-X-TARGETDURATION:%@\n\
43 | #EXT-X-KEY:METHOD=SAMPLE-AES,URI=\"jedi://text.key\"\n\
44 | #EXTINF:%@,\n\
45 | http://localhost:%@\n\
46 | #EXT-X-ENDLIST";
47 | NSInteger duration = 1;
48 | CGFloat EXTINF = 1/15.0; // 15 fps
49 | NSString *host = [NSString stringWithFormat:@"%@/text", @(8989)];
50 | NSString *res = [NSString stringWithFormat:format, @(duration), @(EXTINF), host];
51 | return res;
52 | }
53 |
54 |
55 | @end
56 |
57 | #pragma mark - VTSimplePlayer
58 |
59 | @interface VTSimplePlayer ()
60 |
61 | @property(nonatomic, strong)AVURLAsset *URLAsset;
62 | @property (nonatomic, strong)AVPlayerItem *playerItem;
63 | @property (nonatomic, strong)AVPlayerLayer *playerLayer;
64 | @property (nonatomic, strong) AVPlayer *player;
65 | @property (nonatomic, weak)UIView *containerView;
66 |
67 | @property (nonatomic, strong) VTSimpleResourceLoaderDelegate *resourceLoader;
68 |
69 | @end
70 |
71 | @implementation VTSimplePlayer
72 |
73 | - (void)playURL:(NSString *)url inView:(UIView *)container {
74 | if (![url isKindOfClass:[NSString class]]) {
75 | return;
76 | }
77 | if (url.length==0) return;
78 | if (!container) return;
79 |
80 | _containerView = container;
81 | AVURLAsset *videoURLAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:url] options:nil];
82 | self.URLAsset = videoURLAsset;
83 |
84 | VTSimpleResourceLoaderDelegate *loader = [VTSimpleResourceLoaderDelegate new];
85 | self.resourceLoader = loader;
86 | [self.URLAsset.resourceLoader setDelegate:loader queue:dispatch_get_main_queue()];
87 |
88 | AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:videoURLAsset];
89 | self.playerItem = playerItem;
90 |
91 | self.player = [AVPlayer playerWithPlayerItem:playerItem];
92 | self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
93 | self.playerLayer.frame = CGRectMake(0, 0, container.bounds.size.width, container.bounds.size.height-1);
94 | }
95 |
96 | - (void)resume{
97 | if (!self.playerItem) return;
98 | [self.player play];
99 | }
100 |
101 | - (void)pause{
102 | if (!self.playerItem) return;
103 | [self.player pause];
104 | }
105 |
106 | - (void)stop{
107 | if (!self.player) return;
108 | [self.player pause];
109 | [self.player cancelPendingPrerolls];
110 | if (self.playerLayer) {
111 | [self.playerLayer removeFromSuperlayer];
112 | self.playerLayer = nil;
113 | }
114 | [self.URLAsset.resourceLoader setDelegate:nil queue:dispatch_get_main_queue()];
115 | self.URLAsset = nil;
116 | self.playerItem = nil;
117 | self.player = nil;
118 | }
119 |
120 | -(void)handleShowViewSublayers{
121 | for (UIView *view in _containerView.subviews) {
122 | [view removeFromSuperview];
123 | }
124 | [_containerView.layer addSublayer:self.playerLayer];
125 | }
126 |
127 | -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
128 | if ([keyPath isEqualToString:@"status"]) {
129 | AVPlayerItem *playerItem = (AVPlayerItem *)object;
130 | AVPlayerItemStatus status = playerItem.status;
131 | switch (status) {
132 | case AVPlayerItemStatusUnknown:{
133 | }
134 | break;
135 |
136 | case AVPlayerItemStatusReadyToPlay:{
137 | [self.player play];
138 | [self handleShowViewSublayers];
139 | NSLog(@"duration: %@", @([self duration]));
140 | }
141 | break;
142 |
143 | case AVPlayerItemStatusFailed:{
144 |
145 | }
146 | break;
147 | default:
148 | break;
149 | }
150 | }
151 | else if ([keyPath isEqualToString:@"playbackBufferEmpty"]){
152 |
153 | }
154 | else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]){
155 |
156 | }
157 | }
158 |
159 | - (CGFloat)duration {
160 | CGFloat totalTime = CMTimeGetSeconds(self.playerItem.asset.duration);
161 | return totalTime;
162 | }
163 |
164 |
165 | -(void)setPlayerItem:(AVPlayerItem *)playerItem{
166 | if (_playerItem) {
167 | [_playerItem removeObserver:self forKeyPath:@"status"];
168 | [_playerItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
169 | [_playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
170 | }
171 |
172 | _playerItem = playerItem;
173 |
174 | [_playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
175 | [_playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
176 | [_playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
177 | }
178 |
179 | -(void)setPlayerLayer:(AVPlayerLayer *)playerLayer{
180 | if (_playerLayer) {
181 | [_playerLayer removeFromSuperlayer];
182 | }
183 | _playerLayer = playerLayer;
184 | }
185 |
186 | @end
187 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/SimpleDRMVC/index.m3u8:
--------------------------------------------------------------------------------
1 | #EXTM3U
2 | #EXT-X-VERSION:3
3 | #EXT-X-TARGETDURATION:0
4 | #EXT-X-MEDIA-SEQUENCE:0
5 | #EXTINF:0.066667,
6 | index0.ts
7 | #EXT-X-ENDLIST
8 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/SimpleDRMVC/text.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ohswift/VTAntiScreenCapture/5a24d29c02b70002fc6716f01ccc5b199e27f2ec/Example/VTAntiScreenCapture/SimpleDRMVC/text.mp4
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/VTAntiScreenCapture-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 | NSAppTransportSecurity
49 |
50 | NSAllowsArbitraryLoads
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/VTAntiScreenCapture-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | @import UIKit;
15 | @import Foundation;
16 | #endif
17 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/VTAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // VTAppDelegate.h
3 | // VTAntiScreenCapture
4 | //
5 | // Created by mightyme@qq.com on 12/31/2018.
6 | // Copyright (c) 2018 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface VTAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/VTAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // VTAppDelegate.m
3 | // VTAntiScreenCapture
4 | //
5 | // Created by mightyme@qq.com on 12/31/2018.
6 | // Copyright (c) 2018 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | #import "VTAppDelegate.h"
10 |
11 | @implementation VTAppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/VTDemoTableVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // VCDemoTableVC.h
3 | // VCAntiScreenCapture_Example
4 | //
5 | // Created by Vincent on 2018/12/31.
6 | // Copyright © 2018 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface VTDemoTableVC : UITableViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/VTDemoTableVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // VCDemoTableVC.m
3 | // VCAntiScreenCapture_Example
4 | //
5 | // Created by Vincent on 2018/12/31.
6 | // Copyright © 2018 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | #import "VTDemoTableVC.h"
10 | #import "SimpleDRMVC.h"
11 |
12 | @interface VTDemoTableVC ()
13 |
14 | @end
15 |
16 | @implementation VTDemoTableVC
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 |
21 | // Uncomment the following line to preserve selection between presentations.
22 | // self.clearsSelectionOnViewWillAppear = NO;
23 |
24 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
25 | // self.navigationItem.rightBarButtonItem = self.editButtonItem;
26 | }
27 |
28 | #pragma mark - UITableView Delegate methods
29 |
30 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
31 | UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
32 | UIViewController *vc = nil;
33 | if (indexPath.row == 0) {
34 | vc = [storyBoard instantiateViewControllerWithIdentifier:@"SimpleDRMVC"];
35 | }
36 | else if (indexPath.row == 1) {
37 | vc = [storyBoard instantiateViewControllerWithIdentifier:@"EncodeVC"];
38 | }
39 | if (vc) {
40 | [self.navigationController pushViewController:vc animated:YES];
41 | }
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/VTAntiScreenCapture/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // VTAntiScreenCapture
4 | //
5 | // Created by mightyme@qq.com on 12/31/2018.
6 | // Copyright (c) 2018 mightyme@qq.com. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 | #import "VTAppDelegate.h"
11 |
12 | int main(int argc, char * argv[])
13 | {
14 | @autoreleasepool {
15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([VTAppDelegate class]));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 mightyme@qq.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | iOS实现应用内敏感信息防截屏(附源码),查看 https://www.jianshu.com/p/86d0cfed5f4e
3 |
4 | 喜欢的话,记得给星星哦.
5 |
--------------------------------------------------------------------------------
/VTAntiScreenCapture.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod lib lint VTAntiScreenCapture.podspec' to ensure this is a
3 | # valid spec before submitting.
4 | #
5 | # Any lines starting with a # are optional, but their use is encouraged
6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
7 | #
8 |
9 | Pod::Spec.new do |s|
10 | s.name = 'VTAntiScreenCapture'
11 | s.version = '0.1.0'
12 | s.summary = 'A simple iOS SDK for anti screen capture'
13 |
14 | # This description is used to generate tags and improve search results.
15 | # * Think: What does it do? Why did you write it? What is the focus?
16 | # * Try to keep it short, snappy and to the point.
17 | # * Write the description between the DESC delimiters below.
18 | # * Finally, don't worry about the indent, CocoaPods strips it!
19 |
20 | s.description = <<-DESC
21 | TODO: Add long description of the pod here.
22 | DESC
23 |
24 | s.homepage = 'https://github.com/mightyme@qq.com/VTAntiScreenCapture'
25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
26 | s.license = { :type => 'MIT', :file => 'LICENSE' }
27 | s.author = { 'Vincent' => 'mightyme@qq.com' }
28 | s.source = { :git => 'https://github.com/mightyme@qq.com/VTAntiScreenCapture.git', :tag => s.version.to_s }
29 | # s.social_media_url = 'https://twitter.com/'
30 |
31 | s.ios.deployment_target = '8.0'
32 |
33 | s.source_files = 'VTAntiScreenCapture/Classes/**/*'
34 |
35 | # s.resource_bundles = {
36 | # 'VTAntiScreenCapture' => ['VTAntiScreenCapture/Assets/*.png']
37 | # }
38 |
39 | # s.public_header_files = 'Pod/Classes/**/*.h'
40 | # s.frameworks = 'UIKit', 'MapKit'
41 | # s.dependency 'AFNetworking', '~> 2.3'
42 | end
43 |
--------------------------------------------------------------------------------
/VTAntiScreenCapture/Assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ohswift/VTAntiScreenCapture/5a24d29c02b70002fc6716f01ccc5b199e27f2ec/VTAntiScreenCapture/Assets/.gitkeep
--------------------------------------------------------------------------------
/VTAntiScreenCapture/Classes/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ohswift/VTAntiScreenCapture/5a24d29c02b70002fc6716f01ccc5b199e27f2ec/VTAntiScreenCapture/Classes/.gitkeep
--------------------------------------------------------------------------------
/VTAntiScreenCapture/Classes/UIView+antiCapture.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+antiCapture.h
3 | // AFNetworking
4 | //
5 | // Created by 俞伟山 on 2019/1/1.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface UIView (antiCapture)
13 |
14 | @end
15 |
16 | NS_ASSUME_NONNULL_END
17 |
--------------------------------------------------------------------------------
/VTAntiScreenCapture/Classes/UIView+antiCapture.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+antiCapture.m
3 | // AFNetworking
4 | //
5 | // Created by 俞伟山 on 2019/1/1.
6 | //
7 |
8 | #import "UIView+antiCapture.h"
9 |
10 | @implementation UIView (antiCapture)
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/VTAntiScreenCapture/Classes/VTMP4Encoder.h:
--------------------------------------------------------------------------------
1 | //
2 | // VTMP4Encoder.h
3 | // AFNetworking
4 | //
5 | // Created by Vincent on 2019/1/1.
6 | //
7 |
8 | #import
9 |
10 | @interface VTMP4Encoder : NSObject
11 |
12 | /// 根据视图内容生成mp4文件
13 | + (void)encodeViewToMP4:(UIView *)view completion:(void (^)(NSData *))handler;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/VTAntiScreenCapture/Classes/VTMP4Encoder.m:
--------------------------------------------------------------------------------
1 | //
2 | // VTMP4Encoder.m
3 | // AFNetworking
4 | //
5 | // Created by Vincent on 2019/1/1.
6 | //
7 |
8 | #import "VTMP4Encoder.h"
9 | #import
10 |
11 | @implementation VTMP4Encoder
12 |
13 | + (void)encodeViewToMP4:(UIView *)view completion:(void (^)(NSData *))handler {
14 | UIImage *img = [self viewToImage:view];
15 | [self imageToMP4:img completion:handler];
16 | }
17 |
18 | + (UIImage *)viewToImage:(UIView *)view {
19 | CGSize size = CGSizeMake(view.bounds.size.width, view.bounds.size.height);
20 | UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
21 | CGContextRef currnetContext = UIGraphicsGetCurrentContext();
22 | [view.layer renderInContext:currnetContext];
23 | UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
24 | UIGraphicsEndImageContext();
25 |
26 |
27 | return image;
28 | }
29 |
30 | + (void)imageToMP4:(UIImage *)img completion:(void (^)(NSData *))handler {
31 | NSError *error = nil;
32 |
33 | NSFileManager *fileMgr = [NSFileManager defaultManager];
34 | NSString *documentsDirectory = [NSHomeDirectory()
35 | stringByAppendingPathComponent:@"tmp"];
36 | NSString *videoOutputPath = [documentsDirectory stringByAppendingPathComponent:@"test_output.mp4"];
37 | if ([fileMgr removeItemAtPath:videoOutputPath error:&error] != YES)
38 | NSLog(@"Unable to delete file: %@", [error localizedDescription]);
39 |
40 | CGSize imageSize = CGSizeMake(UIScreen.mainScreen.scale*img.size.width, UIScreen.mainScreen.scale*img.size.height);
41 | NSUInteger fps = 15;
42 | NSArray *imageArray = @[img];
43 |
44 |
45 | NSLog(@"Start building video from defined frames.");
46 |
47 | AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
48 | [NSURL fileURLWithPath:videoOutputPath] fileType:AVFileTypeQuickTimeMovie
49 | error:&error];
50 | /// !!!需要设置faststart
51 | videoWriter.shouldOptimizeForNetworkUse = YES;
52 | NSParameterAssert(videoWriter);
53 |
54 | NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
55 | AVVideoCodecH264, AVVideoCodecKey,
56 | [NSNumber numberWithInt:imageSize.width], AVVideoWidthKey,
57 | [NSNumber numberWithInt:imageSize.height], AVVideoHeightKey,
58 | nil];
59 |
60 | AVAssetWriterInput* videoWriterInput = [AVAssetWriterInput
61 | assetWriterInputWithMediaType:AVMediaTypeVideo
62 | outputSettings:videoSettings];
63 |
64 |
65 | AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
66 | assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput
67 | sourcePixelBufferAttributes:nil];
68 |
69 | NSParameterAssert(videoWriterInput);
70 | NSParameterAssert([videoWriter canAddInput:videoWriterInput]);
71 | videoWriterInput.expectsMediaDataInRealTime = YES;
72 | [videoWriter addInput:videoWriterInput];
73 |
74 | //Start a session:
75 | [videoWriter startWriting];
76 | [videoWriter startSessionAtSourceTime:kCMTimeZero];
77 |
78 | CVPixelBufferRef buffer = NULL;
79 |
80 | //convert uiimage to CGImage.
81 | int frameCount = 0;
82 | double numberOfSecondsPerFrame = 1;
83 | double frameDuration = fps * numberOfSecondsPerFrame;
84 |
85 | //for(VideoFrame * frm in imageArray)
86 | NSLog(@"**************************************************");
87 | for(UIImage * img in imageArray)
88 | {
89 | //UIImage * img = frm._imageFrame;
90 | buffer = [self pixelBufferFromCGImage:[img CGImage]];
91 |
92 | BOOL append_ok = NO;
93 | int j = 0;
94 | while (!append_ok && j < 30) {
95 | if (adaptor.assetWriterInput.readyForMoreMediaData) {
96 | //print out status:
97 | NSLog(@"Processing video frame (%d,%d)",frameCount,[imageArray count]);
98 |
99 | CMTime frameTime = CMTimeMake(frameCount*frameDuration,(int32_t) fps);
100 | append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];
101 | if(!append_ok){
102 | NSError *error = videoWriter.error;
103 | if(error!=nil) {
104 | NSLog(@"Unresolved error %@,%@.", error, [error userInfo]);
105 | }
106 | }
107 | }
108 | else {
109 | printf("adaptor not ready %d, %d\n", frameCount, j);
110 | [NSThread sleepForTimeInterval:0.1];
111 | }
112 | j++;
113 | }
114 | if (!append_ok) {
115 | printf("error appending image %d times %d\n, with error.", frameCount, j);
116 | }
117 | frameCount++;
118 | }
119 | NSLog(@"**************************************************");
120 |
121 | //Finish the session:
122 | [videoWriterInput markAsFinished];
123 | [videoWriter finishWritingWithCompletionHandler:^{
124 | if (handler) {
125 | NSData *data = [NSData dataWithContentsOfFile:videoOutputPath];
126 | handler(data);
127 | }
128 | }];
129 | }
130 |
131 | + (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image {
132 |
133 | CGSize size = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));
134 |
135 | NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
136 | [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
137 | [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
138 | nil];
139 | CVPixelBufferRef pxbuffer = NULL;
140 |
141 | CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,
142 | size.width,
143 | size.height,
144 | kCVPixelFormatType_32ARGB,
145 | (__bridge CFDictionaryRef) options,
146 | &pxbuffer);
147 | if (status != kCVReturnSuccess){
148 | NSLog(@"Failed to create pixel buffer");
149 | }
150 |
151 | CVPixelBufferLockBaseAddress(pxbuffer, 0);
152 | void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
153 |
154 | CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
155 | CGContextRef context = CGBitmapContextCreate(pxdata, size.width,
156 | size.height, 8, 4*size.width, rgbColorSpace,
157 | kCGImageAlphaPremultipliedFirst);
158 | //kCGImageAlphaNoneSkipFirst);
159 | CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
160 | CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
161 | CGImageGetHeight(image)), image);
162 | CGColorSpaceRelease(rgbColorSpace);
163 | CGContextRelease(context);
164 |
165 | CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
166 |
167 | return pxbuffer;
168 | }
169 |
170 |
171 | @end
172 |
--------------------------------------------------------------------------------
/VTAntiScreenCapture/Classes/VTPlayer.h:
--------------------------------------------------------------------------------
1 | //
2 | // VTPlayer.h
3 | // AFNetworking
4 | //
5 | // Created by 俞伟山 on 2019/1/1.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | /// 简单播放器
13 | @interface VTPlayer : NSObject
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/VTAntiScreenCapture/Classes/VTPlayer.m:
--------------------------------------------------------------------------------
1 | //
2 | // VTPlayer.m
3 | // AFNetworking
4 | //
5 | // Created by 俞伟山 on 2019/1/1.
6 | //
7 |
8 | #import "VTPlayer.h"
9 | #import
10 |
11 | @implementation VTPlayer
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/_Pods.xcodeproj:
--------------------------------------------------------------------------------
1 | Example/Pods/Pods.xcodeproj
--------------------------------------------------------------------------------