From b4113ca0510d2a78432e69afe150eb2097d2c54d Mon Sep 17 00:00:00 2001 From: bluepython508 <16466646+bluepython508@users.noreply.github.com> Date: Thu, 1 May 2025 15:20:47 +0100 Subject: [PATCH] Fotekspedi: functional --- .../Fotekspedi.xcodeproj/project.pbxproj | 399 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/swiftpm/Package.resolved | 33 ++ .../UserInterfaceState.xcuserstate | Bin 0 -> 60484 bytes .../xcdebugger/Breakpoints_v2.xcbkptlist | 24 ++ .../xcschemes/xcschememanagement.plist | 14 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 35 ++ .../Fotekspedi/Assets.xcassets/Contents.json | 6 + Fotekspedi/Fotekspedi/ContentView.swift | 62 +++ Fotekspedi/Fotekspedi/FotekspediApp.swift | 10 + Fotekspedi/Fotekspedi/HaishinStreamer.swift | 50 +++ Fotekspedi/Fotekspedi/Info.plist | 5 + 13 files changed, 656 insertions(+) create mode 100644 Fotekspedi/Fotekspedi.xcodeproj/project.pbxproj create mode 100644 Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/xcuserdata/ben.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 Fotekspedi/Fotekspedi.xcodeproj/xcuserdata/ben.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 Fotekspedi/Fotekspedi.xcodeproj/xcuserdata/ben.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 Fotekspedi/Fotekspedi/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Fotekspedi/Fotekspedi/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Fotekspedi/Fotekspedi/Assets.xcassets/Contents.json create mode 100644 Fotekspedi/Fotekspedi/ContentView.swift create mode 100644 Fotekspedi/Fotekspedi/FotekspediApp.swift create mode 100644 Fotekspedi/Fotekspedi/HaishinStreamer.swift create mode 100644 Fotekspedi/Fotekspedi/Info.plist diff --git a/Fotekspedi/Fotekspedi.xcodeproj/project.pbxproj b/Fotekspedi/Fotekspedi.xcodeproj/project.pbxproj new file mode 100644 index 0000000..7b1e8fa --- /dev/null +++ b/Fotekspedi/Fotekspedi.xcodeproj/project.pbxproj @@ -0,0 +1,399 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + B580565F2DC128A70016AC40 /* Atomics in Frameworks */ = {isa = PBXBuildFile; productRef = B580565E2DC128A70016AC40 /* Atomics */; }; + B58056622DC133690016AC40 /* HaishinKit in Frameworks */ = {isa = PBXBuildFile; productRef = B58056612DC133690016AC40 /* HaishinKit */; }; + B58056662DC138620016AC40 /* SRTHaishinKit in Frameworks */ = {isa = PBXBuildFile; productRef = B58056652DC138620016AC40 /* SRTHaishinKit */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + B58056492DC0EE320016AC40 /* Fotekspedi.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Fotekspedi.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + B580565C2DC121B00016AC40 /* Exceptions for "Fotekspedi" folder in "Fotekspedi" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = B58056482DC0EE320016AC40 /* Fotekspedi */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + B580564B2DC0EE320016AC40 /* Fotekspedi */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + B580565C2DC121B00016AC40 /* Exceptions for "Fotekspedi" folder in "Fotekspedi" target */, + ); + path = Fotekspedi; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + B58056462DC0EE320016AC40 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B58056622DC133690016AC40 /* HaishinKit in Frameworks */, + B580565F2DC128A70016AC40 /* Atomics in Frameworks */, + B58056662DC138620016AC40 /* SRTHaishinKit in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + B58056402DC0EE320016AC40 = { + isa = PBXGroup; + children = ( + B580564B2DC0EE320016AC40 /* Fotekspedi */, + B580564A2DC0EE320016AC40 /* Products */, + ); + sourceTree = ""; + }; + B580564A2DC0EE320016AC40 /* Products */ = { + isa = PBXGroup; + children = ( + B58056492DC0EE320016AC40 /* Fotekspedi.app */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B58056482DC0EE320016AC40 /* Fotekspedi */ = { + isa = PBXNativeTarget; + buildConfigurationList = B58056542DC0EE330016AC40 /* Build configuration list for PBXNativeTarget "Fotekspedi" */; + buildPhases = ( + B58056452DC0EE320016AC40 /* Sources */, + B58056462DC0EE320016AC40 /* Frameworks */, + B58056472DC0EE320016AC40 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + B580564B2DC0EE320016AC40 /* Fotekspedi */, + ); + name = Fotekspedi; + packageProductDependencies = ( + B580565E2DC128A70016AC40 /* Atomics */, + B58056612DC133690016AC40 /* HaishinKit */, + B58056652DC138620016AC40 /* SRTHaishinKit */, + ); + productName = Fotekspedi; + productReference = B58056492DC0EE320016AC40 /* Fotekspedi.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B58056412DC0EE320016AC40 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1630; + LastUpgradeCheck = 1630; + TargetAttributes = { + B58056482DC0EE320016AC40 = { + CreatedOnToolsVersion = 16.3; + }; + }; + }; + buildConfigurationList = B58056442DC0EE320016AC40 /* Build configuration list for PBXProject "Fotekspedi" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B58056402DC0EE320016AC40; + minimizedProjectReferenceProxies = 1; + packageReferences = ( + B580565D2DC128A70016AC40 /* XCRemoteSwiftPackageReference "swift-atomics" */, + B58056602DC133690016AC40 /* XCRemoteSwiftPackageReference "HaishinKit" */, + ); + preferredProjectObjectVersion = 77; + productRefGroup = B580564A2DC0EE320016AC40 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B58056482DC0EE320016AC40 /* Fotekspedi */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B58056472DC0EE320016AC40 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B58056452DC0EE320016AC40 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + B58056522DC0EE330016AC40 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = X4J63B4MDT; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.4; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B58056532DC0EE330016AC40 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = X4J63B4MDT; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.4; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B58056552DC0EE330016AC40 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = X4J63B4MDT; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Fotekspedi/Info.plist; + INFOPLIST_KEY_NSCameraUsageDescription = "The use of the camera is the purpose of this app."; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = net.soroos.ben.Fotekspedi; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B58056562DC0EE330016AC40 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = X4J63B4MDT; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Fotekspedi/Info.plist; + INFOPLIST_KEY_NSCameraUsageDescription = "The use of the camera is the purpose of this app."; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = net.soroos.ben.Fotekspedi; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B58056442DC0EE320016AC40 /* Build configuration list for PBXProject "Fotekspedi" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B58056522DC0EE330016AC40 /* Debug */, + B58056532DC0EE330016AC40 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B58056542DC0EE330016AC40 /* Build configuration list for PBXNativeTarget "Fotekspedi" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B58056552DC0EE330016AC40 /* Debug */, + B58056562DC0EE330016AC40 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + B580565D2DC128A70016AC40 /* XCRemoteSwiftPackageReference "swift-atomics" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/swift-atomics.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.2.0; + }; + }; + B58056602DC133690016AC40 /* XCRemoteSwiftPackageReference "HaishinKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/HaishinKit/HaishinKit.swift"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.0.7; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + B580565E2DC128A70016AC40 /* Atomics */ = { + isa = XCSwiftPackageProductDependency; + package = B580565D2DC128A70016AC40 /* XCRemoteSwiftPackageReference "swift-atomics" */; + productName = Atomics; + }; + B58056612DC133690016AC40 /* HaishinKit */ = { + isa = XCSwiftPackageProductDependency; + package = B58056602DC133690016AC40 /* XCRemoteSwiftPackageReference "HaishinKit" */; + productName = HaishinKit; + }; + B58056652DC138620016AC40 /* SRTHaishinKit */ = { + isa = XCSwiftPackageProductDependency; + package = B58056602DC133690016AC40 /* XCRemoteSwiftPackageReference "HaishinKit" */; + productName = SRTHaishinKit; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = B58056412DC0EE320016AC40 /* Project object */; +} diff --git a/Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..3782a26 --- /dev/null +++ b/Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,33 @@ +{ + "originHash" : "8ec6314649f7cf6de235c936fc7ca7563d16e73fa8eff226a772330bdc962181", + "pins" : [ + { + "identity" : "haishinkit.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/HaishinKit/HaishinKit.swift", + "state" : { + "revision" : "f0bcea8e22b6bf27f339eeb3339333243a60796a", + "version" : "2.0.7" + } + }, + { + "identity" : "logboard", + "kind" : "remoteSourceControl", + "location" : "https://github.com/shogo4405/Logboard.git", + "state" : { + "revision" : "272976e1f3e8873e60ffe4b08fe50df48a93751b", + "version" : "2.5.0" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics.git", + "state" : { + "revision" : "cd142fd2f64be2100422d658e7411e39489da985", + "version" : "1.2.0" + } + } + ], + "version" : 3 +} diff --git a/Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/xcuserdata/ben.xcuserdatad/UserInterfaceState.xcuserstate b/Fotekspedi/Fotekspedi.xcodeproj/project.xcworkspace/xcuserdata/ben.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..d79f411a71f6ce842d088e5ba257111c2bee44d5 GIT binary patch literal 60484 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 + + + + + + + + diff --git a/Fotekspedi/Fotekspedi.xcodeproj/xcuserdata/ben.xcuserdatad/xcschemes/xcschememanagement.plist b/Fotekspedi/Fotekspedi.xcodeproj/xcuserdata/ben.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..459d8c9 --- /dev/null +++ b/Fotekspedi/Fotekspedi.xcodeproj/xcuserdata/ben.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + Fotekspedi.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/Fotekspedi/Fotekspedi/Assets.xcassets/AccentColor.colorset/Contents.json b/Fotekspedi/Fotekspedi/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Fotekspedi/Fotekspedi/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fotekspedi/Fotekspedi/Assets.xcassets/AppIcon.appiconset/Contents.json b/Fotekspedi/Fotekspedi/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/Fotekspedi/Fotekspedi/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fotekspedi/Fotekspedi/Assets.xcassets/Contents.json b/Fotekspedi/Fotekspedi/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Fotekspedi/Fotekspedi/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fotekspedi/Fotekspedi/ContentView.swift b/Fotekspedi/Fotekspedi/ContentView.swift new file mode 100644 index 0000000..971bdc8 --- /dev/null +++ b/Fotekspedi/Fotekspedi/ContentView.swift @@ -0,0 +1,62 @@ +import SwiftUI + +enum StreamState { + case disconnected + case error(Error) + case waiting + case connected(Stream) +} +// TODO: error handling on errors while running + + +struct ContentView: View { + @State var state: StreamState = .disconnected { + didSet { + UIApplication.shared.isIdleTimerDisabled = switch (state) { + case .disconnected, .error(_): false + case .waiting, .connected(_): true + } + } + } + var body: some View { + VStack { + switch (state) { + case .disconnected: Button("Connect", action: self.connect) + case .error(let err): error(err) + case .waiting: ProgressView() + case .connected(_): Button("Disconnect", action: self.disconnect) + } + }.padding() + } + + func error(_ err: Error) -> some View { + return VStack { + Text(verbatim: err.localizedDescription) + Button("Reconnect", action: self.connect) + } + } + + func connect() { + state = .waiting + Task { + do { + state = .connected(try await Stream(to: URL(string: "srt://10.97.15.1:8890?mode=listen&streamid=publish:fotekspedi&pkt_size=1316")!)) + } catch (let err) { + state = .error(err) + } + } + } + + func disconnect() { + guard case .connected(let stream) = self.state else { return } + Task { + state = .waiting + await stream.stop() + state = .disconnected + } + } +} + +#Preview { + ContentView() +} diff --git a/Fotekspedi/Fotekspedi/FotekspediApp.swift b/Fotekspedi/Fotekspedi/FotekspediApp.swift new file mode 100644 index 0000000..75c368f --- /dev/null +++ b/Fotekspedi/Fotekspedi/FotekspediApp.swift @@ -0,0 +1,10 @@ +import SwiftUI + +@main +struct FotekspediApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/Fotekspedi/Fotekspedi/HaishinStreamer.swift b/Fotekspedi/Fotekspedi/HaishinStreamer.swift new file mode 100644 index 0000000..b3e95a8 --- /dev/null +++ b/Fotekspedi/Fotekspedi/HaishinStreamer.swift @@ -0,0 +1,50 @@ +import AVFoundation +import HaishinKit +import SRTHaishinKit + +internal var isAuthorized: Bool { + get async { + let status = AVCaptureDevice.authorizationStatus(for: .video) + var isAuthorized = status == .authorized + if status == .notDetermined { + isAuthorized = await AVCaptureDevice.requestAccess(for: .video) + } + return isAuthorized + } +} + +enum StreamError: Error { + case notAuthorized +} + +class Stream { + var mixer: MediaMixer + let connection: SRTConnection + let stream: SRTStream + + init(to url: URL) async throws { + guard await isAuthorized else { throw StreamError.notAuthorized } + + mixer = MediaMixer() + await mixer.setVideoOrientation(.landscapeRight) + await mixer.setSessionPreset(.hd1280x720) + connection = SRTConnection() + try await connection.setSocketOption(SRTSocketOption(name: .latency, value: 1)) + stream = SRTStream(connection: connection) + await stream.setVideoSettings(.init(videoSize: .init(width: 1280, height: 720), bitRate: 10 * 1000 * 1000)) + + + + try await mixer.attachVideo(AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)) + + await mixer.addOutput(stream) + + try await connection.connect(url) + await stream.publish() + } + + func stop() async { + await mixer.stopRunning() + } +} + diff --git a/Fotekspedi/Fotekspedi/Info.plist b/Fotekspedi/Fotekspedi/Info.plist new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/Fotekspedi/Fotekspedi/Info.plist @@ -0,0 +1,5 @@ + + + + +