Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Mux-Upload-SDK.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = 'Mux-Upload-SDK'
s.module_name = 'MuxUploadSDK'
s.version = '0.3.1'
s.version = '0.6.0'
s.summary = 'Upload video to Mux.'
s.description = 'A library for uploading video to Mux. Similar to UpChunk, but for iOS.'

Expand Down
75 changes: 55 additions & 20 deletions Sources/MuxUploadSDK/InternalUtilities/Reporting/Reporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,36 @@
//

import Foundation
import UIKit

fileprivate func processInfoOperationSystemVersion() -> String {
let version = ProcessInfo().operatingSystemVersion
return "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)"
}

fileprivate func posixModelName() -> String {
var systemName = utsname()
uname(&systemName)
return withUnsafePointer(to: &systemName.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
ptr in String.init(validatingUTF8: ptr)
}
} ?? "Unknown"
}

fileprivate func inferredPlatformName() -> String {
let modelName = posixModelName().lowercased()
if modelName.contains("ipad") {
return "iPadOS"
} else if modelName.contains("iphone") {
return "iOS"
} else {
#if targetEnvironment(simulator)
return "Simulator"
#else
return "Unknown"
#endif
}
}

class Reporter: NSObject {

Expand All @@ -28,9 +57,11 @@ class Reporter: NSObject {
var locale: Locale {
Locale.current
}
var device: UIDevice {
UIDevice.current
}

let model: String
let platformName: String
let platformVersion: String

var regionCode: String? {
if #available(iOS 16, *) {
return locale.language.region?.identifier
Expand All @@ -52,6 +83,10 @@ class Reporter: NSObject {
string: "https://mobile.muxanalytics.com"
)!

self.model = posixModelName()
self.platformName = inferredPlatformName()
self.platformVersion = processInfoOperationSystemVersion()

super.init()

let sessionConfig: URLSessionConfiguration = URLSessionConfiguration.default
Expand Down Expand Up @@ -105,14 +140,14 @@ extension Reporter {
let data = UploadSucceededEvent.Data(
appName: Bundle.main.appName,
appVersion: Bundle.main.appVersion,
deviceModel: device.model,
deviceModel: model,
inputDuration: inputDuration,
inputSize: inputSize,
inputStandardizationRequested: options.inputStandardization.isRequested,
platformName: device.systemName,
platformVersion: device.systemVersion,
platformName: platformName,
platformVersion: platformVersion,
regionCode: regionCode,
sdkVersion: Version.versionString,
sdkVersion: SemanticVersion.versionString,
uploadStartTime: uploadStartTime,
uploadEndTime: uploadEndTime,
uploadURL: uploadURL
Expand Down Expand Up @@ -145,15 +180,15 @@ extension Reporter {
let data = UploadFailedEvent.Data(
appName: Bundle.main.appName,
appVersion: Bundle.main.appVersion,
deviceModel: device.model,
deviceModel: model,
errorDescription: errorDescription,
inputDuration: inputDuration,
inputSize: inputSize,
inputStandardizationRequested: options.inputStandardization.isRequested,
platformName: device.systemName,
platformVersion: device.systemVersion,
platformName: platformName,
platformVersion: platformVersion,
regionCode: regionCode,
sdkVersion: Version.versionString,
sdkVersion: SemanticVersion.versionString,
uploadStartTime: uploadStartTime,
uploadEndTime: uploadEndTime,
uploadURL: url
Expand Down Expand Up @@ -186,15 +221,15 @@ extension Reporter {
let data = InputStandardizationSucceededEvent.Data(
appName: Bundle.main.appName,
appVersion: Bundle.main.appVersion,
deviceModel: device.model,
deviceModel: model,
inputDuration: inputDuration,
inputSize: inputSize,
maximumResolution: options.inputStandardization.maximumResolution.description,
nonStandardInputReasons: nonStandardInputReasons.map(\.description),
platformName: device.systemName,
platformVersion: device.systemVersion,
platformName: platformName,
platformVersion: platformVersion,
regionCode: regionCode,
sdkVersion: Version.versionString,
sdkVersion: SemanticVersion.versionString,
standardizationStartTime: standardizationStartTime,
standardizationEndTime: standardizationEndTime,
uploadURL: uploadURL
Expand Down Expand Up @@ -229,16 +264,16 @@ extension Reporter {
let data = InputStandardizationFailedEvent.Data(
appName: Bundle.main.appName,
appVersion: Bundle.main.appVersion,
deviceModel: device.model,
deviceModel: model,
errorDescription: errorDescription,
inputDuration: inputDuration,
inputSize: inputSize,
maximumResolution: options.inputStandardization.maximumResolution.description,
nonStandardInputReasons: nonStandardInputReasons.map(\.description),
platformName: device.systemName,
platformVersion: device.systemVersion,
platformName: platformName,
platformVersion: platformVersion,
regionCode: regionCode,
sdkVersion: Version.versionString,
sdkVersion: SemanticVersion.versionString,
standardizationStartTime: standardizationStartTime,
standardizationEndTime: standardizationEndTime,
uploadCanceled: uploadCanceled,
Expand Down
5 changes: 5 additions & 0 deletions Sources/MuxUploadSDK/PublicAPI/DirectUpload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import AVFoundation
import Foundation

/// Indicates whether a finished upload failed due to an error
/// or succeeded along with details
public typealias DirectUploadResult = Result<DirectUpload.SuccessDetails, DirectUploadError>

///
Expand Down Expand Up @@ -341,6 +343,9 @@ public final class DirectUpload {
*/
public var progressHandler: StateHandler?

/**
Details about a ``DirectUpload`` after it successfully finished
*/
public struct SuccessDetails : Sendable, Hashable {
public let finalState: TransportStatus
}
Expand Down
143 changes: 105 additions & 38 deletions Sources/MuxUploadSDK/PublicAPI/Options/DirectUploadOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,65 @@

import Foundation

// MARK: - Direct Upload Options

/// Options for the direct upload
public struct DirectUploadOptions {

// MARK: - Transport Options

/// Options to control the SDK network operations to
/// transport the direct upload input to Mux
/// Options for tuning network transport of direct upload
/// chunks to Mux. Using the ``default`` is recommended
/// for most applications.
public struct Transport {

/// At least 8M is recommended
/// The size of each file chunk in bytes sent by the
/// SDK during an upload. At least 8MB is recommended.
public var chunkSizeInBytes: Int

/// Number of retry attempts per chunk if the
/// associated request fails
/// Number of retry attempts per chunk if its upload
/// request is unsuccessful
public var retryLimitPerChunk: Int

/// A default set of transport options: 8MB chunk
/// size and chunk request retry limit of 3
/// Default options for ``DirectUpload`` chunk transport
/// over the network. The chunk size is 8MB and the
/// per-chunk retry limit is 3.
public static var `default`: Transport {
Transport(
chunkSizeInBytes: 8 * 1024 * 1024,
retryLimitPerChunk: 3
)
}

/// Initializes options that govern network transport
/// by the SDK
///
/// Initializes options for transport of upload chunks
/// over the network
/// - Parameters:
/// - chunkSize: the size of each file chunk in
/// bytes the SDK sends when uploading, default
/// value is 8MB
/// - retriesPerChunk: number of retry attempts
/// if the chunk request fails, default value is 3
/// - chunkSize: the size of each file chunk sent
/// by the SDK during an upload.
/// Defaults to 8MB.
/// - retryLimitPerChunk: number of times a failed
/// chunk request is retried. Default limit is
/// 3 retries.
public init(
chunkSize: Measurement<UnitInformationStorage> = .defaultDirectUploadChunkSize,
retryLimitPerChunk: Int = 3
) {
self.chunkSizeInBytes = Int(
abs(chunkSize.converted(to: .bytes).value)
.rounded(.down)
)
self.retryLimitPerChunk = retryLimitPerChunk
}

/// Initializes options for transport of upload chunks
/// over the network
/// - Parameters:
/// - chunkSizeInBytes: the size of each file
/// chunk in bytes the SDK uploads in a single
/// request. Default chunk size is 8MB.
/// - retryLimitPerChunk: number of times a failed
/// chunk request is retried. Default limit is
/// 3 retries.
public init(
chunkSizeInBytes: Int = 8 * 1024 * 1024,
retryLimitPerChunk: Int = 3
Expand All @@ -47,12 +72,14 @@ public struct DirectUploadOptions {
}
}

/// Transport options for the direct upload
/// Network transport options for direct upload chunks
public var transport: Transport

// MARK: - Input Standardization Options

/// Options controlling direct upload input standardization
/// Options for adjusments made by ``DirectUpload``
/// to some inputs to minimize processing time during
/// ingestion
public struct InputStandardization {

/// If requested the SDK will attempt to detect
Expand Down Expand Up @@ -124,8 +151,8 @@ public struct DirectUploadOptions {
maximumResolution: .default
)

// Kept private to an invalid combination of parameters
// being used for initialization
// Kept private to avoid an invalid combination of
// parameters being used for initialization
private init(
isRequested: Bool,
maximumResolution: MaximumResolution
Expand All @@ -134,10 +161,8 @@ public struct DirectUploadOptions {
self.maximumResolution = maximumResolution
}

/// Used to initialize ``DirectUploadOptions.InputStandardization``
/// with that enables input standardization with
/// a maximum resolution
///
/// Initializes options that request input
/// standardization with a custom maximum resolution
/// - Parameters:
/// - maximumResolution: the maximum resolution
/// of the standardized input
Expand Down Expand Up @@ -186,12 +211,14 @@ public struct DirectUploadOptions {

// MARK: Direct Upload Options Initializers

/// Initializes options that dictate how the direct upload
/// is carried out by the SDK
/// - Parameters:
/// - inputStandardization: options to enable or
/// disable standardizing the format of the direct
/// upload inputs, it is requested by default. To
/// prevent the SDK from making any changes to the
/// format of the input use ``DirectUploadOptions.InputStandardization.skipped``
/// - inputStandardization: options related to input
/// standardization. Input standardization is requested
/// by default.
/// To skip input standardization pass in
/// ``DirectUploadOptions.InputStandardization.skipped``.
/// - transport: options for transporting the
/// direct upload input to Mux
/// - eventTracking: event tracking options for the
Expand All @@ -206,19 +233,49 @@ public struct DirectUploadOptions {
self.eventTracking = eventTracking
}

/// Initializes options that dictate how the direct upload
/// is carried out by the SDK
/// - Parameters:
/// - eventTracking: event tracking options for the
/// direct upload
/// - inputStandardization: options related to input
/// standardization. Input standardization is requested
/// by default.
/// To skip input standardization pass in
/// ``DirectUploadOptions.InputStandardization.skipped``.
/// - chunkSize: The size of each file chunk sent by
/// the SDK during an upload. Defaults to 8MB.
/// - retryLimitPerChunk: number of retry attempts
/// if the chunk request fails. Defaults to 3.
public init(
eventTracking: EventTracking = .default,
inputStandardization: InputStandardization = .default,
chunkSize: Measurement<UnitInformationStorage> = .defaultDirectUploadChunkSize,
retryLimitPerChunk: Int = 3
) {
self.eventTracking = eventTracking
self.inputStandardization = inputStandardization
self.transport = Transport(
chunkSize: chunkSize,
retryLimitPerChunk: retryLimitPerChunk
)
}

/// Initializes options that dictate how the direct upload
/// is carried out by the SDK
/// - Parameters:
/// - eventTracking: event tracking options for the
/// direct upload
/// - inputStandardization: options to enable or
/// disable standardizing the format of the direct
/// upload inputs, it is requested by default. To
/// prevent the SDK from making any changes to the
/// format of the input use ``DirectUploadOptions.InputStandardization.skipped``
/// - chunkSize: the size of each file chunk in
/// bytes the SDK sends when uploading, default
/// value is 8MB
/// - retriesPerChunk: number of retry attempts
/// if the chunk request fails, default value is 3
/// - inputStandardization: options related to input
/// standardization. Input standardization is requested
/// by default.
/// To skip input standardization pass in
/// ``DirectUploadOptions.InputStandardization.skipped``.
/// - chunkSizeInBytes: The size of each file chunk
/// in bytes sent by the SDK during an upload.
/// Defaults to 8MB.
/// - retryLimitPerChunk: number of retry attempts
/// if the chunk request fails. Defaults to 3.
public init(
eventTracking: EventTracking = .default,
inputStandardization: InputStandardization = .default,
Expand All @@ -237,6 +294,16 @@ public struct DirectUploadOptions {

// MARK: - Extensions

extension Measurement where UnitType == UnitInformationStorage {
/// Default direct upload chunk size
public static var defaultDirectUploadChunkSize: Self {
Measurement(
value: 8,
unit: .megabytes
)
}
}

extension DirectUploadOptions.InputStandardization.MaximumResolution: CustomStringConvertible {
public var description: String {
switch self {
Expand Down
Loading