├── .gitignore ├── OpenGLVideoMerge.xcodeproj ├── .LSOverride ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── OpenGLVideoMerge.xcworkspace └── contents.xcworkspacedata ├── OpenGLVideoMerge ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── Main.storyboard ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── OpenGLVideoMerge-Info.plist ├── OpenGLVideoMerge-Prefix.pch ├── ViewController.h ├── ViewController.m ├── en.lproj │ └── InfoPlist.strings └── main.m ├── Podfile ├── Podfile.lock ├── README.md ├── README.rd ├── Results ├── Both Audios Tracks.mov ├── No Audios.mov └── One Audio.mov └── movies ├── FXSample 8 Seconds.mov ├── FXSample.mov ├── FXSample_no_audio.mov ├── Record 8 Seconds.mov ├── record.mov └── record_no_audio.mov /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | OpenGLVideoMerge.xcodeproj/project.xcworkspace/xcshareddata 3 | 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # CocoaPods 25 | # 26 | # We recommend against adding the Pods directory to your .gitignore. However 27 | # you should judge for yourself, the pros and cons are mentioned at: 28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 29 | # 30 | Pods/ -------------------------------------------------------------------------------- /OpenGLVideoMerge.xcodeproj/.LSOverride: -------------------------------------------------------------------------------- 1 | /Applications/Xcode.app -------------------------------------------------------------------------------- /OpenGLVideoMerge.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1C20E25F3657385DC58D048D /* README.rd in Resources */ = {isa = PBXBuildFile; fileRef = 1C20E702FB061606573A7EBE /* README.rd */; }; 11 | 1C20E5451320705AE6458B63 /* FXSample.mov in Resources */ = {isa = PBXBuildFile; fileRef = 1C20E8C50A1BF34BFE290AD5 /* FXSample.mov */; }; 12 | A5483C7422048E0DC9098D93 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A66AE30BADFE4D6AB73FD241 /* libPods.a */; }; 13 | A9B6079D1A6168060080AC89 /* FXSample 8 Seconds.mov in Resources */ = {isa = PBXBuildFile; fileRef = A9B607971A6168060080AC89 /* FXSample 8 Seconds.mov */; }; 14 | A9B6079E1A6168060080AC89 /* FXSample_no_audio.mov in Resources */ = {isa = PBXBuildFile; fileRef = A9B607981A6168060080AC89 /* FXSample_no_audio.mov */; }; 15 | A9B607A01A6168060080AC89 /* Record 8 Seconds.mov in Resources */ = {isa = PBXBuildFile; fileRef = A9B6079A1A6168060080AC89 /* Record 8 Seconds.mov */; }; 16 | A9B607A11A6168060080AC89 /* record_no_audio.mov in Resources */ = {isa = PBXBuildFile; fileRef = A9B6079B1A6168060080AC89 /* record_no_audio.mov */; }; 17 | A9B607A21A6168060080AC89 /* record.mov in Resources */ = {isa = PBXBuildFile; fileRef = A9B6079C1A6168060080AC89 /* record.mov */; }; 18 | A9E9498E182E252000ED5693 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E9498D182E252000ED5693 /* Foundation.framework */; }; 19 | A9E94990182E252000ED5693 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E9498F182E252000ED5693 /* CoreGraphics.framework */; }; 20 | A9E94992182E252000ED5693 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E94991182E252000ED5693 /* UIKit.framework */; }; 21 | A9E94998182E252000ED5693 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A9E94996182E252000ED5693 /* InfoPlist.strings */; }; 22 | A9E9499A182E252000ED5693 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E94999182E252000ED5693 /* main.m */; }; 23 | A9E9499E182E252000ED5693 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E9499D182E252000ED5693 /* AppDelegate.m */; }; 24 | A9E949A1182E252000ED5693 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A9E9499F182E252000ED5693 /* Main.storyboard */; }; 25 | A9E949A4182E252000ED5693 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E949A3182E252000ED5693 /* ViewController.m */; }; 26 | A9E949A6182E252000ED5693 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A9E949A5182E252000ED5693 /* Images.xcassets */; }; 27 | A9E949AD182E252000ED5693 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E949AC182E252000ED5693 /* XCTest.framework */; }; 28 | A9E949AE182E252000ED5693 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E9498D182E252000ED5693 /* Foundation.framework */; }; 29 | A9E949AF182E252000ED5693 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E94991182E252000ED5693 /* UIKit.framework */; }; 30 | A9E949C3182E252E00ED5693 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E949C2182E252E00ED5693 /* OpenGLES.framework */; }; 31 | A9E949C5182E253200ED5693 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E949C4182E253200ED5693 /* QuartzCore.framework */; }; 32 | A9E949C7182E253600ED5693 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E949C6182E253600ED5693 /* AVFoundation.framework */; }; 33 | A9E949CB182E254100ED5693 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E949CA182E254100ED5693 /* CoreVideo.framework */; }; 34 | A9E949E3182E343900ED5693 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E949E2182E343900ED5693 /* AssetsLibrary.framework */; }; 35 | /* End PBXBuildFile section */ 36 | 37 | /* Begin PBXContainerItemProxy section */ 38 | A9E949B0182E252000ED5693 /* PBXContainerItemProxy */ = { 39 | isa = PBXContainerItemProxy; 40 | containerPortal = A9E94982182E252000ED5693 /* Project object */; 41 | proxyType = 1; 42 | remoteGlobalIDString = A9E94989182E252000ED5693; 43 | remoteInfo = OpenGLVideoMerge; 44 | }; 45 | /* End PBXContainerItemProxy section */ 46 | 47 | /* Begin PBXFileReference section */ 48 | 1C20E702FB061606573A7EBE /* README.rd */ = {isa = PBXFileReference; lastKnownFileType = file.rd; path = README.rd; sourceTree = ""; }; 49 | 1C20E8C50A1BF34BFE290AD5 /* FXSample.mov */ = {isa = PBXFileReference; lastKnownFileType = video.quicktime; path = FXSample.mov; sourceTree = ""; }; 50 | 3F3E023F4BB659646F21BF4A /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 51 | A66AE30BADFE4D6AB73FD241 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | A9B607971A6168060080AC89 /* FXSample 8 Seconds.mov */ = {isa = PBXFileReference; lastKnownFileType = video.quicktime; path = "FXSample 8 Seconds.mov"; sourceTree = ""; }; 53 | A9B607981A6168060080AC89 /* FXSample_no_audio.mov */ = {isa = PBXFileReference; lastKnownFileType = video.quicktime; path = FXSample_no_audio.mov; sourceTree = ""; }; 54 | A9B6079A1A6168060080AC89 /* Record 8 Seconds.mov */ = {isa = PBXFileReference; lastKnownFileType = video.quicktime; path = "Record 8 Seconds.mov"; sourceTree = ""; }; 55 | A9B6079B1A6168060080AC89 /* record_no_audio.mov */ = {isa = PBXFileReference; lastKnownFileType = video.quicktime; path = record_no_audio.mov; sourceTree = ""; }; 56 | A9B6079C1A6168060080AC89 /* record.mov */ = {isa = PBXFileReference; lastKnownFileType = video.quicktime; path = record.mov; sourceTree = ""; }; 57 | A9E9498A182E252000ED5693 /* OpenGLVideoMerge.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OpenGLVideoMerge.app; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | A9E9498D182E252000ED5693 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 59 | A9E9498F182E252000ED5693 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 60 | A9E94991182E252000ED5693 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 61 | A9E94995182E252000ED5693 /* OpenGLVideoMerge-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OpenGLVideoMerge-Info.plist"; sourceTree = ""; }; 62 | A9E94997182E252000ED5693 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 63 | A9E94999182E252000ED5693 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 64 | A9E9499B182E252000ED5693 /* OpenGLVideoMerge-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OpenGLVideoMerge-Prefix.pch"; sourceTree = ""; }; 65 | A9E9499C182E252000ED5693 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 66 | A9E9499D182E252000ED5693 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 67 | A9E949A0182E252000ED5693 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 68 | A9E949A2182E252000ED5693 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 69 | A9E949A3182E252000ED5693 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 70 | A9E949A5182E252000ED5693 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 71 | A9E949AB182E252000ED5693 /* OpenGLVideoMergeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OpenGLVideoMergeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 72 | A9E949AC182E252000ED5693 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 73 | A9E949C2182E252E00ED5693 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; 74 | A9E949C4182E253200ED5693 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 75 | A9E949C6182E253600ED5693 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 76 | A9E949C8182E253B00ED5693 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; 77 | A9E949CA182E254100ED5693 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; 78 | A9E949E2182E343900ED5693 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; 79 | C6E222EEBE8E80921B9251D2 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; 80 | /* End PBXFileReference section */ 81 | 82 | /* Begin PBXFrameworksBuildPhase section */ 83 | A9E94987182E252000ED5693 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | A9E949E3182E343900ED5693 /* AssetsLibrary.framework in Frameworks */, 88 | A9E949CB182E254100ED5693 /* CoreVideo.framework in Frameworks */, 89 | A9E949C7182E253600ED5693 /* AVFoundation.framework in Frameworks */, 90 | A9E949C5182E253200ED5693 /* QuartzCore.framework in Frameworks */, 91 | A9E949C3182E252E00ED5693 /* OpenGLES.framework in Frameworks */, 92 | A9E94990182E252000ED5693 /* CoreGraphics.framework in Frameworks */, 93 | A9E94992182E252000ED5693 /* UIKit.framework in Frameworks */, 94 | A9E9498E182E252000ED5693 /* Foundation.framework in Frameworks */, 95 | A5483C7422048E0DC9098D93 /* libPods.a in Frameworks */, 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | A9E949A8182E252000ED5693 /* Frameworks */ = { 100 | isa = PBXFrameworksBuildPhase; 101 | buildActionMask = 2147483647; 102 | files = ( 103 | A9E949AD182E252000ED5693 /* XCTest.framework in Frameworks */, 104 | A9E949AF182E252000ED5693 /* UIKit.framework in Frameworks */, 105 | A9E949AE182E252000ED5693 /* Foundation.framework in Frameworks */, 106 | ); 107 | runOnlyForDeploymentPostprocessing = 0; 108 | }; 109 | /* End PBXFrameworksBuildPhase section */ 110 | 111 | /* Begin PBXGroup section */ 112 | 9E194C6115C50E2E9132D3CA /* Pods */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | C6E222EEBE8E80921B9251D2 /* Pods.debug.xcconfig */, 116 | 3F3E023F4BB659646F21BF4A /* Pods.release.xcconfig */, 117 | ); 118 | name = Pods; 119 | sourceTree = ""; 120 | }; 121 | A9E94981182E252000ED5693 = { 122 | isa = PBXGroup; 123 | children = ( 124 | A9E94993182E252000ED5693 /* OpenGLVideoMerge */, 125 | A9E9498C182E252000ED5693 /* Frameworks */, 126 | A9E9498B182E252000ED5693 /* Products */, 127 | 1C20E702FB061606573A7EBE /* README.rd */, 128 | 9E194C6115C50E2E9132D3CA /* Pods */, 129 | ); 130 | sourceTree = ""; 131 | }; 132 | A9E9498B182E252000ED5693 /* Products */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | A9E9498A182E252000ED5693 /* OpenGLVideoMerge.app */, 136 | A9E949AB182E252000ED5693 /* OpenGLVideoMergeTests.xctest */, 137 | ); 138 | name = Products; 139 | sourceTree = ""; 140 | }; 141 | A9E9498C182E252000ED5693 /* Frameworks */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | A9E949E2182E343900ED5693 /* AssetsLibrary.framework */, 145 | A9E949CA182E254100ED5693 /* CoreVideo.framework */, 146 | A9E949C8182E253B00ED5693 /* CoreMedia.framework */, 147 | A9E949C6182E253600ED5693 /* AVFoundation.framework */, 148 | A9E949C4182E253200ED5693 /* QuartzCore.framework */, 149 | A9E949C2182E252E00ED5693 /* OpenGLES.framework */, 150 | A9E9498D182E252000ED5693 /* Foundation.framework */, 151 | A9E9498F182E252000ED5693 /* CoreGraphics.framework */, 152 | A9E94991182E252000ED5693 /* UIKit.framework */, 153 | A9E949AC182E252000ED5693 /* XCTest.framework */, 154 | A66AE30BADFE4D6AB73FD241 /* libPods.a */, 155 | ); 156 | name = Frameworks; 157 | sourceTree = ""; 158 | }; 159 | A9E94993182E252000ED5693 /* OpenGLVideoMerge */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | A9E949CC182E264100ED5693 /* movies */, 163 | A9E9499C182E252000ED5693 /* AppDelegate.h */, 164 | A9E9499D182E252000ED5693 /* AppDelegate.m */, 165 | A9E9499F182E252000ED5693 /* Main.storyboard */, 166 | A9E949A2182E252000ED5693 /* ViewController.h */, 167 | A9E949A3182E252000ED5693 /* ViewController.m */, 168 | A9E949A5182E252000ED5693 /* Images.xcassets */, 169 | A9E94994182E252000ED5693 /* Supporting Files */, 170 | ); 171 | path = OpenGLVideoMerge; 172 | sourceTree = ""; 173 | }; 174 | A9E94994182E252000ED5693 /* Supporting Files */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | A9E94995182E252000ED5693 /* OpenGLVideoMerge-Info.plist */, 178 | A9E94996182E252000ED5693 /* InfoPlist.strings */, 179 | A9E94999182E252000ED5693 /* main.m */, 180 | A9E9499B182E252000ED5693 /* OpenGLVideoMerge-Prefix.pch */, 181 | ); 182 | name = "Supporting Files"; 183 | sourceTree = ""; 184 | }; 185 | A9E949CC182E264100ED5693 /* movies */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | 1C20E8C50A1BF34BFE290AD5 /* FXSample.mov */, 189 | A9B607971A6168060080AC89 /* FXSample 8 Seconds.mov */, 190 | A9B607981A6168060080AC89 /* FXSample_no_audio.mov */, 191 | A9B6079A1A6168060080AC89 /* Record 8 Seconds.mov */, 192 | A9B6079B1A6168060080AC89 /* record_no_audio.mov */, 193 | A9B6079C1A6168060080AC89 /* record.mov */, 194 | ); 195 | path = movies; 196 | sourceTree = SOURCE_ROOT; 197 | }; 198 | /* End PBXGroup section */ 199 | 200 | /* Begin PBXNativeTarget section */ 201 | A9E94989182E252000ED5693 /* OpenGLVideoMerge */ = { 202 | isa = PBXNativeTarget; 203 | buildConfigurationList = A9E949BC182E252000ED5693 /* Build configuration list for PBXNativeTarget "OpenGLVideoMerge" */; 204 | buildPhases = ( 205 | 964A27ABEB7A740238A9B350 /* Check Pods Manifest.lock */, 206 | A9E94986182E252000ED5693 /* Sources */, 207 | A9E94987182E252000ED5693 /* Frameworks */, 208 | A9E94988182E252000ED5693 /* Resources */, 209 | 234A5E2CB2E3F43FE895505D /* Copy Pods Resources */, 210 | ); 211 | buildRules = ( 212 | ); 213 | dependencies = ( 214 | ); 215 | name = OpenGLVideoMerge; 216 | productName = OpenGLVideoMerge; 217 | productReference = A9E9498A182E252000ED5693 /* OpenGLVideoMerge.app */; 218 | productType = "com.apple.product-type.application"; 219 | }; 220 | A9E949AA182E252000ED5693 /* OpenGLVideoMergeTests */ = { 221 | isa = PBXNativeTarget; 222 | buildConfigurationList = A9E949BF182E252000ED5693 /* Build configuration list for PBXNativeTarget "OpenGLVideoMergeTests" */; 223 | buildPhases = ( 224 | A9E949A7182E252000ED5693 /* Sources */, 225 | A9E949A8182E252000ED5693 /* Frameworks */, 226 | A9E949A9182E252000ED5693 /* Resources */, 227 | ); 228 | buildRules = ( 229 | ); 230 | dependencies = ( 231 | A9E949B1182E252000ED5693 /* PBXTargetDependency */, 232 | ); 233 | name = OpenGLVideoMergeTests; 234 | productName = OpenGLVideoMergeTests; 235 | productReference = A9E949AB182E252000ED5693 /* OpenGLVideoMergeTests.xctest */; 236 | productType = "com.apple.product-type.bundle.unit-test"; 237 | }; 238 | /* End PBXNativeTarget section */ 239 | 240 | /* Begin PBXProject section */ 241 | A9E94982182E252000ED5693 /* Project object */ = { 242 | isa = PBXProject; 243 | attributes = { 244 | LastUpgradeCheck = 0500; 245 | ORGANIZATIONNAME = Tuo; 246 | TargetAttributes = { 247 | A9E949AA182E252000ED5693 = { 248 | TestTargetID = A9E94989182E252000ED5693; 249 | }; 250 | }; 251 | }; 252 | buildConfigurationList = A9E94985182E252000ED5693 /* Build configuration list for PBXProject "OpenGLVideoMerge" */; 253 | compatibilityVersion = "Xcode 3.2"; 254 | developmentRegion = English; 255 | hasScannedForEncodings = 0; 256 | knownRegions = ( 257 | en, 258 | Base, 259 | ); 260 | mainGroup = A9E94981182E252000ED5693; 261 | productRefGroup = A9E9498B182E252000ED5693 /* Products */; 262 | projectDirPath = ""; 263 | projectRoot = ""; 264 | targets = ( 265 | A9E94989182E252000ED5693 /* OpenGLVideoMerge */, 266 | A9E949AA182E252000ED5693 /* OpenGLVideoMergeTests */, 267 | ); 268 | }; 269 | /* End PBXProject section */ 270 | 271 | /* Begin PBXResourcesBuildPhase section */ 272 | A9E94988182E252000ED5693 /* Resources */ = { 273 | isa = PBXResourcesBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | A9E949A6182E252000ED5693 /* Images.xcassets in Resources */, 277 | A9B607A21A6168060080AC89 /* record.mov in Resources */, 278 | A9E94998182E252000ED5693 /* InfoPlist.strings in Resources */, 279 | A9B607A01A6168060080AC89 /* Record 8 Seconds.mov in Resources */, 280 | A9B607A11A6168060080AC89 /* record_no_audio.mov in Resources */, 281 | A9E949A1182E252000ED5693 /* Main.storyboard in Resources */, 282 | A9B6079E1A6168060080AC89 /* FXSample_no_audio.mov in Resources */, 283 | A9B6079D1A6168060080AC89 /* FXSample 8 Seconds.mov in Resources */, 284 | 1C20E25F3657385DC58D048D /* README.rd in Resources */, 285 | 1C20E5451320705AE6458B63 /* FXSample.mov in Resources */, 286 | ); 287 | runOnlyForDeploymentPostprocessing = 0; 288 | }; 289 | A9E949A9182E252000ED5693 /* Resources */ = { 290 | isa = PBXResourcesBuildPhase; 291 | buildActionMask = 2147483647; 292 | files = ( 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | /* End PBXResourcesBuildPhase section */ 297 | 298 | /* Begin PBXShellScriptBuildPhase section */ 299 | 234A5E2CB2E3F43FE895505D /* Copy Pods Resources */ = { 300 | isa = PBXShellScriptBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | ); 304 | inputPaths = ( 305 | ); 306 | name = "Copy Pods Resources"; 307 | outputPaths = ( 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | shellPath = /bin/sh; 311 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; 312 | showEnvVarsInLog = 0; 313 | }; 314 | 964A27ABEB7A740238A9B350 /* Check Pods Manifest.lock */ = { 315 | isa = PBXShellScriptBuildPhase; 316 | buildActionMask = 2147483647; 317 | files = ( 318 | ); 319 | inputPaths = ( 320 | ); 321 | name = "Check Pods Manifest.lock"; 322 | outputPaths = ( 323 | ); 324 | runOnlyForDeploymentPostprocessing = 0; 325 | shellPath = /bin/sh; 326 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 327 | showEnvVarsInLog = 0; 328 | }; 329 | /* End PBXShellScriptBuildPhase section */ 330 | 331 | /* Begin PBXSourcesBuildPhase section */ 332 | A9E94986182E252000ED5693 /* Sources */ = { 333 | isa = PBXSourcesBuildPhase; 334 | buildActionMask = 2147483647; 335 | files = ( 336 | A9E949A4182E252000ED5693 /* ViewController.m in Sources */, 337 | A9E9499E182E252000ED5693 /* AppDelegate.m in Sources */, 338 | A9E9499A182E252000ED5693 /* main.m in Sources */, 339 | ); 340 | runOnlyForDeploymentPostprocessing = 0; 341 | }; 342 | A9E949A7182E252000ED5693 /* Sources */ = { 343 | isa = PBXSourcesBuildPhase; 344 | buildActionMask = 2147483647; 345 | files = ( 346 | ); 347 | runOnlyForDeploymentPostprocessing = 0; 348 | }; 349 | /* End PBXSourcesBuildPhase section */ 350 | 351 | /* Begin PBXTargetDependency section */ 352 | A9E949B1182E252000ED5693 /* PBXTargetDependency */ = { 353 | isa = PBXTargetDependency; 354 | target = A9E94989182E252000ED5693 /* OpenGLVideoMerge */; 355 | targetProxy = A9E949B0182E252000ED5693 /* PBXContainerItemProxy */; 356 | }; 357 | /* End PBXTargetDependency section */ 358 | 359 | /* Begin PBXVariantGroup section */ 360 | A9E94996182E252000ED5693 /* InfoPlist.strings */ = { 361 | isa = PBXVariantGroup; 362 | children = ( 363 | A9E94997182E252000ED5693 /* en */, 364 | ); 365 | name = InfoPlist.strings; 366 | sourceTree = ""; 367 | }; 368 | A9E9499F182E252000ED5693 /* Main.storyboard */ = { 369 | isa = PBXVariantGroup; 370 | children = ( 371 | A9E949A0182E252000ED5693 /* Base */, 372 | ); 373 | name = Main.storyboard; 374 | sourceTree = ""; 375 | }; 376 | /* End PBXVariantGroup section */ 377 | 378 | /* Begin XCBuildConfiguration section */ 379 | A9E949BA182E252000ED5693 /* Debug */ = { 380 | isa = XCBuildConfiguration; 381 | buildSettings = { 382 | ALWAYS_SEARCH_USER_PATHS = NO; 383 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 384 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 385 | CLANG_CXX_LIBRARY = "libc++"; 386 | CLANG_ENABLE_MODULES = YES; 387 | CLANG_ENABLE_OBJC_ARC = YES; 388 | CLANG_WARN_BOOL_CONVERSION = YES; 389 | CLANG_WARN_CONSTANT_CONVERSION = YES; 390 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 391 | CLANG_WARN_EMPTY_BODY = YES; 392 | CLANG_WARN_ENUM_CONVERSION = YES; 393 | CLANG_WARN_INT_CONVERSION = YES; 394 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 395 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 396 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 397 | COPY_PHASE_STRIP = NO; 398 | GCC_C_LANGUAGE_STANDARD = gnu99; 399 | GCC_DYNAMIC_NO_PIC = NO; 400 | GCC_OPTIMIZATION_LEVEL = 0; 401 | GCC_PREPROCESSOR_DEFINITIONS = ( 402 | "DEBUG=1", 403 | "$(inherited)", 404 | ); 405 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 406 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 407 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 408 | GCC_WARN_UNDECLARED_SELECTOR = YES; 409 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 410 | GCC_WARN_UNUSED_FUNCTION = YES; 411 | GCC_WARN_UNUSED_VARIABLE = YES; 412 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 413 | ONLY_ACTIVE_ARCH = YES; 414 | SDKROOT = iphoneos; 415 | }; 416 | name = Debug; 417 | }; 418 | A9E949BB182E252000ED5693 /* Release */ = { 419 | isa = XCBuildConfiguration; 420 | buildSettings = { 421 | ALWAYS_SEARCH_USER_PATHS = NO; 422 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 423 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 424 | CLANG_CXX_LIBRARY = "libc++"; 425 | CLANG_ENABLE_MODULES = YES; 426 | CLANG_ENABLE_OBJC_ARC = YES; 427 | CLANG_WARN_BOOL_CONVERSION = YES; 428 | CLANG_WARN_CONSTANT_CONVERSION = YES; 429 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 430 | CLANG_WARN_EMPTY_BODY = YES; 431 | CLANG_WARN_ENUM_CONVERSION = YES; 432 | CLANG_WARN_INT_CONVERSION = YES; 433 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 434 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 435 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 436 | COPY_PHASE_STRIP = YES; 437 | ENABLE_NS_ASSERTIONS = NO; 438 | GCC_C_LANGUAGE_STANDARD = gnu99; 439 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 440 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 441 | GCC_WARN_UNDECLARED_SELECTOR = YES; 442 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 443 | GCC_WARN_UNUSED_FUNCTION = YES; 444 | GCC_WARN_UNUSED_VARIABLE = YES; 445 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 446 | SDKROOT = iphoneos; 447 | VALIDATE_PRODUCT = YES; 448 | }; 449 | name = Release; 450 | }; 451 | A9E949BD182E252000ED5693 /* Debug */ = { 452 | isa = XCBuildConfiguration; 453 | baseConfigurationReference = C6E222EEBE8E80921B9251D2 /* Pods.debug.xcconfig */; 454 | buildSettings = { 455 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 456 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 457 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 458 | GCC_PREFIX_HEADER = "OpenGLVideoMerge/OpenGLVideoMerge-Prefix.pch"; 459 | INFOPLIST_FILE = "OpenGLVideoMerge/OpenGLVideoMerge-Info.plist"; 460 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 461 | PRODUCT_NAME = "$(TARGET_NAME)"; 462 | WRAPPER_EXTENSION = app; 463 | }; 464 | name = Debug; 465 | }; 466 | A9E949BE182E252000ED5693 /* Release */ = { 467 | isa = XCBuildConfiguration; 468 | baseConfigurationReference = 3F3E023F4BB659646F21BF4A /* Pods.release.xcconfig */; 469 | buildSettings = { 470 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 471 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 472 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 473 | GCC_PREFIX_HEADER = "OpenGLVideoMerge/OpenGLVideoMerge-Prefix.pch"; 474 | INFOPLIST_FILE = "OpenGLVideoMerge/OpenGLVideoMerge-Info.plist"; 475 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 476 | PRODUCT_NAME = "$(TARGET_NAME)"; 477 | WRAPPER_EXTENSION = app; 478 | }; 479 | name = Release; 480 | }; 481 | A9E949C0182E252000ED5693 /* Debug */ = { 482 | isa = XCBuildConfiguration; 483 | buildSettings = { 484 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 485 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/OpenGLVideoMerge.app/OpenGLVideoMerge"; 486 | FRAMEWORK_SEARCH_PATHS = ( 487 | "$(SDKROOT)/Developer/Library/Frameworks", 488 | "$(inherited)", 489 | "$(DEVELOPER_FRAMEWORKS_DIR)", 490 | ); 491 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 492 | GCC_PREFIX_HEADER = "OpenGLVideoMerge/OpenGLVideoMerge-Prefix.pch"; 493 | GCC_PREPROCESSOR_DEFINITIONS = ( 494 | "DEBUG=1", 495 | "$(inherited)", 496 | ); 497 | INFOPLIST_FILE = "OpenGLVideoMergeTests/OpenGLVideoMergeTests-Info.plist"; 498 | PRODUCT_NAME = "$(TARGET_NAME)"; 499 | TEST_HOST = "$(BUNDLE_LOADER)"; 500 | WRAPPER_EXTENSION = xctest; 501 | }; 502 | name = Debug; 503 | }; 504 | A9E949C1182E252000ED5693 /* Release */ = { 505 | isa = XCBuildConfiguration; 506 | buildSettings = { 507 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 508 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/OpenGLVideoMerge.app/OpenGLVideoMerge"; 509 | FRAMEWORK_SEARCH_PATHS = ( 510 | "$(SDKROOT)/Developer/Library/Frameworks", 511 | "$(inherited)", 512 | "$(DEVELOPER_FRAMEWORKS_DIR)", 513 | ); 514 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 515 | GCC_PREFIX_HEADER = "OpenGLVideoMerge/OpenGLVideoMerge-Prefix.pch"; 516 | INFOPLIST_FILE = "OpenGLVideoMergeTests/OpenGLVideoMergeTests-Info.plist"; 517 | PRODUCT_NAME = "$(TARGET_NAME)"; 518 | TEST_HOST = "$(BUNDLE_LOADER)"; 519 | WRAPPER_EXTENSION = xctest; 520 | }; 521 | name = Release; 522 | }; 523 | /* End XCBuildConfiguration section */ 524 | 525 | /* Begin XCConfigurationList section */ 526 | A9E94985182E252000ED5693 /* Build configuration list for PBXProject "OpenGLVideoMerge" */ = { 527 | isa = XCConfigurationList; 528 | buildConfigurations = ( 529 | A9E949BA182E252000ED5693 /* Debug */, 530 | A9E949BB182E252000ED5693 /* Release */, 531 | ); 532 | defaultConfigurationIsVisible = 0; 533 | defaultConfigurationName = Release; 534 | }; 535 | A9E949BC182E252000ED5693 /* Build configuration list for PBXNativeTarget "OpenGLVideoMerge" */ = { 536 | isa = XCConfigurationList; 537 | buildConfigurations = ( 538 | A9E949BD182E252000ED5693 /* Debug */, 539 | A9E949BE182E252000ED5693 /* Release */, 540 | ); 541 | defaultConfigurationIsVisible = 0; 542 | defaultConfigurationName = Release; 543 | }; 544 | A9E949BF182E252000ED5693 /* Build configuration list for PBXNativeTarget "OpenGLVideoMergeTests" */ = { 545 | isa = XCConfigurationList; 546 | buildConfigurations = ( 547 | A9E949C0182E252000ED5693 /* Debug */, 548 | A9E949C1182E252000ED5693 /* Release */, 549 | ); 550 | defaultConfigurationIsVisible = 0; 551 | defaultConfigurationName = Release; 552 | }; 553 | /* End XCConfigurationList section */ 554 | }; 555 | rootObject = A9E94982182E252000ED5693 /* Project object */; 556 | } 557 | -------------------------------------------------------------------------------- /OpenGLVideoMerge.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OpenGLVideoMerge.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /OpenGLVideoMerge/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // OpenGLVideoMerge 4 | // 5 | // Created by Tuo on 11/9/13. 6 | // Copyright (c) 2013 Tuo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /OpenGLVideoMerge/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // OpenGLVideoMerge 4 | // 5 | // Created by Tuo on 11/9/13. 6 | // Copyright (c) 2013 Tuo. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | NSString *folderPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 16 | NSError *error = nil; 17 | for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folderPath error:&error]) { 18 | ALog(@"delete file: %@", file.lastPathComponent); 19 | [[NSFileManager defaultManager] removeItemAtPath:[folderPath stringByAppendingPathComponent:file] error:&error]; 20 | } 21 | 22 | 23 | 24 | // Override point for customization after application launch. 25 | return YES; 26 | } 27 | 28 | - (void)applicationWillResignActive:(UIApplication *)application 29 | { 30 | // 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. 31 | // 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. 32 | } 33 | 34 | - (void)applicationDidEnterBackground:(UIApplication *)application 35 | { 36 | // 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. 37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 38 | } 39 | 40 | - (void)applicationWillEnterForeground:(UIApplication *)application 41 | { 42 | // 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. 43 | } 44 | 45 | - (void)applicationDidBecomeActive:(UIApplication *)application 46 | { 47 | // 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. 48 | } 49 | 50 | - (void)applicationWillTerminate:(UIApplication *)application 51 | { 52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /OpenGLVideoMerge/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 32 | 41 | 50 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /OpenGLVideoMerge/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "60x60", 21 | "scale" : "3x" 22 | } 23 | ], 24 | "info" : { 25 | "version" : 1, 26 | "author" : "xcode" 27 | } 28 | } -------------------------------------------------------------------------------- /OpenGLVideoMerge/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /OpenGLVideoMerge/OpenGLVideoMerge-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | tuo.test.${PRODUCT_NAME:rfc1034identifier} 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 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /OpenGLVideoMerge/OpenGLVideoMerge-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 15 | #import 16 | 17 | #import "Util.h" 18 | 19 | typedef void (^EmptyBlock) (); 20 | 21 | #define CMTimeDebug(frameTime) CFBridgingRelease(CMTimeCopyDescription(kCFAllocatorDefault, frameTime)) 22 | 23 | #define CurrentQueueLabel dispatch_queue_get_label(dispatch_get_current_queue()) 24 | 25 | //#define NSLog(fmt, ...) NSLog((@"%s " fmt), CurrentQueueLabel, ##__VA_ARGS__) 26 | 27 | #define ALog(fmt, ...) NSLog(fmt, ##__VA_ARGS__) 28 | 29 | // #define NSLog(...) 30 | 31 | #define UTIL [Util shared] 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /OpenGLVideoMerge/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // OpenGLVideoMerge 4 | // 5 | // Created by Tuo on 11/9/13. 6 | // Copyright (c) 2013 Tuo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class VideoWriter; 12 | 13 | @interface ViewController : UIViewController 14 | 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /OpenGLVideoMerge/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // OpenGLVideoMerge 4 | // 5 | // Created by Tuo on 11/9/13. 6 | // Copyright (c) 2013 Tuo. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "SVProgressHUD.h" 11 | 12 | 13 | #import 14 | #import 15 | #import 16 | #import 17 | 18 | #import 19 | #import 20 | #import 21 | 22 | @interface ViewController () 23 | @property (strong, nonatomic) IBOutlet UIButton *startMergeBtn; 24 | @property (weak, nonatomic) IBOutlet UILabel *gpuResultLabel; 25 | @property (weak, nonatomic) IBOutlet UILabel *customResultLabel; 26 | 27 | @property (weak, nonatomic) IBOutlet UILabel *videoMergeTipName; 28 | 29 | @property (nonatomic, strong) GPUImageMovie *gpuMovieFX; 30 | @property (nonatomic, strong) GPUImageMovie *gpuMovieA; 31 | @property (nonatomic, strong) GPUImageMovieWriter *movieWriter; 32 | @property (nonatomic, strong) GPUImageChromaKeyBlendFilter *filter; 33 | @property (nonatomic, strong) ALAssetsLibrary *library; 34 | 35 | @property(nonatomic) NSDate *startDate; 36 | @property(nonatomic) NSURL *outputURL; 37 | 38 | @property(nonatomic) dispatch_group_t recordSyncingDispatchGroup; 39 | @end 40 | 41 | @implementation ViewController { 42 | 43 | NSURL *fxURL,*rawVideoURL; 44 | } 45 | 46 | 47 | 48 | - (void)viewDidLoad 49 | { 50 | [super viewDidLoad]; 51 | 52 | 53 | 54 | 55 | } 56 | 57 | 58 | - (void)didReceiveMemoryWarning 59 | { 60 | [super didReceiveMemoryWarning]; 61 | // Dispose of any resources that can be recreated. 62 | } 63 | 64 | - (IBAction)onMergeAllAudios:(id)sender { 65 | [self gpuimageProcessWithFXMovieName: @"FXSample" rawMovieName: @"record"]; 66 | } 67 | 68 | 69 | - (IBAction)onMergeOnlyOneAudio:(id)sender { 70 | [self gpuimageProcessWithFXMovieName: @"FXSample" rawMovieName: @"record_no_audio"]; 71 | //[self gpuimageProcessWithFXMovieName: @"FXSample_no_audio" rawMovieName: @"record"]; 72 | } 73 | - (IBAction)onMergeNoAudioAtAll:(id)sender { 74 | [self gpuimageProcessWithFXMovieName: @"FXSample_no_audio" rawMovieName: @"record_no_audio"]; 75 | } 76 | 77 | - (void)gpuimageProcessWithFXMovieName:(NSString *)fxName rawMovieName:(NSString *)rawName { 78 | //tips on how to use ffmpeg to extract audio track from video 79 | //ffmpeg -i FXSample.mov -vcodec copy -an FXSample_no_audio.mov 80 | //ffmpeg -i record.mov -vcodec copy -an record_no_audio.mov 81 | 82 | 83 | fxURL = [[NSBundle mainBundle] URLForResource:fxName withExtension:@"mov"]; 84 | rawVideoURL = [[NSBundle mainBundle] URLForResource:rawName withExtension:@"mov"]; 85 | 86 | self.videoMergeTipName.text = [NSString stringWithFormat:@"FX:%@, RAW: %@", fxName, rawName]; 87 | 88 | 89 | [SVProgressHUD showWithStatus:@"processing..."]; 90 | self.startDate = [NSDate date]; 91 | self.gpuMovieA = [[GPUImageMovie alloc] initWithURL:rawVideoURL]; 92 | 93 | self.gpuMovieFX = [[GPUImageMovie alloc] initWithURL:fxURL]; 94 | 95 | 96 | self.filter = [[GPUImageChromaKeyBlendFilter alloc] init]; 97 | [self.filter forceProcessingAtSize:CGSizeMake(640/2, 640/2)]; 98 | 99 | [self.gpuMovieFX addTarget:self.filter]; 100 | [self.gpuMovieA addTarget:self.filter]; 101 | 102 | 103 | //setup writer 104 | NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/gpu_output.mov"]; 105 | unlink([pathToMovie UTF8String]); // If a file already exists, AVAssetWriter won't let you record new frames, so delete the old movie 106 | self.outputURL = [NSURL fileURLWithPath:pathToMovie]; 107 | self.movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:self.outputURL size:CGSizeMake(640.0/2, 640.0/2)]; 108 | [self.filter addTarget:self.movieWriter]; 109 | 110 | NSArray *movies = @[self.gpuMovieA, self.gpuMovieFX]; 111 | 112 | 113 | dispatch_group_t movieReadyDispatchGroup = dispatch_group_create(); 114 | for(GPUImageMovie *movie in movies){ 115 | [movie loadAsset:movieReadyDispatchGroup]; 116 | } 117 | 118 | __weak typeof(self) weakSelf = self; 119 | dispatch_group_notify(movieReadyDispatchGroup, dispatch_get_main_queue(), ^{ 120 | NSLog(@"all movies are ready to process :)"); 121 | 122 | NSMutableArray *audioTracks = [NSMutableArray array]; 123 | for(GPUImageMovie *movie in movies){ 124 | AVAssetTrack *track = [movie.asset tracksWithMediaType:AVMediaTypeAudio].firstObject; 125 | if(track){ 126 | [audioTracks addObject:track]; 127 | } 128 | } 129 | 130 | if(audioTracks.count > 0){ 131 | [self.movieWriter setupAudioReaderWithTracks:audioTracks]; 132 | [self.movieWriter setHasAudioTrack:YES]; //use default audio settings, setup asset writer audio 133 | } 134 | 135 | 136 | self.recordSyncingDispatchGroup = dispatch_group_create(); 137 | 138 | //this has to be called before, to make sure all audio/video in movie writer is set 139 | [self.movieWriter startRecording]; 140 | 141 | 142 | //video handling 143 | dispatch_group_enter(self.recordSyncingDispatchGroup); 144 | [self.gpuMovieA startProcessing]; 145 | [self.gpuMovieFX startProcessing]; 146 | 147 | [self.movieWriter setCompletionBlock:^{ 148 | [weakSelf.gpuMovieFX endProcessing]; 149 | [weakSelf.gpuMovieA endProcessing]; 150 | [weakSelf.movieWriter finishVideoRecordingWithCompletionHandler:^{ 151 | //[SVProgressHUD showSuccessWithStatus:@"Done"]; 152 | NSLog(@"===video wrote is done"); 153 | dispatch_group_leave(weakSelf.recordSyncingDispatchGroup); 154 | }]; 155 | }]; 156 | 157 | 158 | 159 | //audio handling 160 | dispatch_group_enter(self.recordSyncingDispatchGroup); 161 | [self.movieWriter startAudioRecording]; 162 | [self.movieWriter startAudioWritingWithComplectionBlock:^{ 163 | NSLog(@"====audio wring is done"); 164 | dispatch_group_leave(weakSelf.recordSyncingDispatchGroup); 165 | }]; 166 | 167 | 168 | 169 | dispatch_group_notify(self.recordSyncingDispatchGroup, dispatch_get_main_queue(), ^{ 170 | NSLog(@"vidoe and audio writing are both done-----------------"); 171 | [self.movieWriter finishRecordingWithCompletionHandler:^{ 172 | NSLog(@"final clean up is done :)"); 173 | [weakSelf writeToAlbum:weakSelf.outputURL]; 174 | 175 | dispatch_async(dispatch_get_main_queue(), ^{ 176 | [SVProgressHUD showSuccessWithStatus:@"Done"]; 177 | NSString *time = [NSString stringWithFormat:@"GPU: %f seconds.", -([weakSelf.startDate timeIntervalSinceNow])]; 178 | 179 | weakSelf.gpuResultLabel.text = time; 180 | }); 181 | }]; 182 | }); 183 | 184 | }); 185 | 186 | 187 | 188 | 189 | } 190 | 191 | 192 | - (void)writeToAlbum:(NSURL *)outputFileURL{ 193 | self.library = [[ALAssetsLibrary alloc] init]; 194 | if ([_library videoAtPathIsCompatibleWithSavedPhotosAlbum:outputFileURL]) 195 | { 196 | [_library writeVideoAtPathToSavedPhotosAlbum:outputFileURL 197 | completionBlock:^(NSURL *assetURL, NSError *error) 198 | { 199 | if (error) 200 | { 201 | dispatch_async(dispatch_get_main_queue(), ^{ 202 | [SVProgressHUD showErrorWithStatus:@"failed"]; 203 | }); 204 | NSLog(@"fail to saved: %@", error); 205 | }else{ 206 | NSLog(@"saved"); 207 | dispatch_async(dispatch_get_main_queue(), ^{ 208 | [SVProgressHUD showSuccessWithStatus:@"saved"]; 209 | }); 210 | } 211 | }]; 212 | } 213 | } 214 | 215 | 216 | 217 | 218 | @end 219 | -------------------------------------------------------------------------------- /OpenGLVideoMerge/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /OpenGLVideoMerge/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // OpenGLVideoMerge 4 | // 5 | // Created by Tuo on 11/9/13. 6 | // Copyright (c) 2013 Tuo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '7.0' 2 | 3 | # ignore all warnings from all pods 4 | inhibit_all_warnings! 5 | 6 | #pod 'GPUImage', :path => '~/Documents/git/spikes/BL/GPUImage' 7 | 8 | pod 'GPUImage', :git => 'https://github.com/tuo/GPUImage.git' 9 | pod 'SVProgressHUD' 10 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - GPUImage (0.1.6) 3 | - SVProgressHUD (1.0) 4 | 5 | DEPENDENCIES: 6 | - GPUImage (from `~/Documents/git/spikes/BL/GPUImage`) 7 | - SVProgressHUD 8 | 9 | EXTERNAL SOURCES: 10 | GPUImage: 11 | :path: ~/Documents/git/spikes/BL/GPUImage 12 | 13 | SPEC CHECKSUMS: 14 | GPUImage: 7750b6b093f36b7d843cbcdae97ab63cd91b8fe6 15 | SVProgressHUD: 5034c6e22b8c2ca3e09402e48d41ed0340aa1c50 16 | 17 | COCOAPODS: 0.35.0 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GPUImageMultpileAudioTracksMerge 2 | 3 | GPUImage Movie Writer - Added Multiple Audio Track Writing Support 4 | 5 | See more detail on my blog: [GPUImage Movie Writer: Merging All Audio Tracks From Multiple Movies](http://tuohuang.info/gpuimage-movie-writer--merging-all-audio-tracks-from-multiple-movies) 6 | 7 | -------------------------------------------------------------------------------- /README.rd: -------------------------------------------------------------------------------- 1 | # GPUImage Movie Writer - Added Multiple Audio Track Writing Support 2 | 3 | See more detail on my blog: []() -------------------------------------------------------------------------------- /Results/Both Audios Tracks.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuo/GPUImageMultpileAudioTracksMerge/fc646c827dba22ce1517bd3d51de86ad2c55f4aa/Results/Both Audios Tracks.mov -------------------------------------------------------------------------------- /Results/No Audios.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuo/GPUImageMultpileAudioTracksMerge/fc646c827dba22ce1517bd3d51de86ad2c55f4aa/Results/No Audios.mov -------------------------------------------------------------------------------- /Results/One Audio.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuo/GPUImageMultpileAudioTracksMerge/fc646c827dba22ce1517bd3d51de86ad2c55f4aa/Results/One Audio.mov -------------------------------------------------------------------------------- /movies/FXSample 8 Seconds.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuo/GPUImageMultpileAudioTracksMerge/fc646c827dba22ce1517bd3d51de86ad2c55f4aa/movies/FXSample 8 Seconds.mov -------------------------------------------------------------------------------- /movies/FXSample.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuo/GPUImageMultpileAudioTracksMerge/fc646c827dba22ce1517bd3d51de86ad2c55f4aa/movies/FXSample.mov -------------------------------------------------------------------------------- /movies/FXSample_no_audio.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuo/GPUImageMultpileAudioTracksMerge/fc646c827dba22ce1517bd3d51de86ad2c55f4aa/movies/FXSample_no_audio.mov -------------------------------------------------------------------------------- /movies/Record 8 Seconds.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuo/GPUImageMultpileAudioTracksMerge/fc646c827dba22ce1517bd3d51de86ad2c55f4aa/movies/Record 8 Seconds.mov -------------------------------------------------------------------------------- /movies/record.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuo/GPUImageMultpileAudioTracksMerge/fc646c827dba22ce1517bd3d51de86ad2c55f4aa/movies/record.mov -------------------------------------------------------------------------------- /movies/record_no_audio.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuo/GPUImageMultpileAudioTracksMerge/fc646c827dba22ce1517bd3d51de86ad2c55f4aa/movies/record_no_audio.mov --------------------------------------------------------------------------------