Skip to content

Commit a1637e3

Browse files
committed
Split to three files
1 parent b318d4e commit a1637e3

4 files changed

Lines changed: 384 additions & 370 deletions

File tree

FDWaveformView.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
/* Begin PBXBuildFile section */
1010
D94BE1CF1CCEBFD80042282A /* FDWaveformView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D94BE1CE1CCEBFD80042282A /* FDWaveformView.swift */; };
11+
D993BD581EBA3D110022A881 /* FDAudioContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D993BD571EBA3D110022A881 /* FDAudioContext.swift */; };
12+
D993BD5A1EBA3F570022A881 /* FDWaveformRenderOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D993BD591EBA3F570022A881 /* FDWaveformRenderOperation.swift */; };
1113
D9FEF4BF1CCEBC0F0013FBDD /* FDWaveformView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D9FEF4B41CCEBC0D0013FBDD /* FDWaveformView.framework */; };
1214
D9FEF4C41CCEBC100013FBDD /* FDWaveformViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9FEF4C31CCEBC100013FBDD /* FDWaveformViewTests.swift */; };
1315
/* End PBXBuildFile section */
@@ -24,6 +26,8 @@
2426

2527
/* Begin PBXFileReference section */
2628
D94BE1CE1CCEBFD80042282A /* FDWaveformView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FDWaveformView.swift; sourceTree = "<group>"; };
29+
D993BD571EBA3D110022A881 /* FDAudioContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FDAudioContext.swift; sourceTree = "<group>"; };
30+
D993BD591EBA3F570022A881 /* FDWaveformRenderOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FDWaveformRenderOperation.swift; sourceTree = "<group>"; };
2731
D9FEF4B41CCEBC0D0013FBDD /* FDWaveformView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FDWaveformView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
2832
D9FEF4B91CCEBC0D0013FBDD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Source/Info.plist; sourceTree = "<group>"; };
2933
D9FEF4BE1CCEBC0F0013FBDD /* FDWaveformViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FDWaveformViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -81,6 +85,8 @@
8185
isa = PBXGroup;
8286
children = (
8387
D94BE1CE1CCEBFD80042282A /* FDWaveformView.swift */,
88+
D993BD571EBA3D110022A881 /* FDAudioContext.swift */,
89+
D993BD591EBA3F570022A881 /* FDWaveformRenderOperation.swift */,
8490
);
8591
path = Source;
8692
sourceTree = "<group>";
@@ -203,6 +209,8 @@
203209
isa = PBXSourcesBuildPhase;
204210
buildActionMask = 2147483647;
205211
files = (
212+
D993BD581EBA3D110022A881 /* FDAudioContext.swift in Sources */,
213+
D993BD5A1EBA3F570022A881 /* FDWaveformRenderOperation.swift in Sources */,
206214
D94BE1CF1CCEBFD80042282A /* FDWaveformView.swift in Sources */,
207215
);
208216
runOnlyForDeploymentPostprocessing = 0;

Source/FDAudioContext.swift

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//
2+
// Copyright 2013 - 2017, William Entriken and the FDWaveformView contributors.
3+
//
4+
import UIKit
5+
import AVFoundation
6+
7+
/// Holds audio information used for building waveforms
8+
final class FDAudioContext {
9+
10+
/// The audio asset URL used to load the context
11+
public let audioURL: URL
12+
13+
/// Total number of samples in loaded asset
14+
public let totalSamples: Int
15+
16+
/// Loaded asset
17+
public let asset: AVAsset
18+
19+
// Loaded assetTrack
20+
public let assetTrack: AVAssetTrack
21+
22+
private init(audioURL: URL, totalSamples: Int, asset: AVAsset, assetTrack: AVAssetTrack) {
23+
self.audioURL = audioURL
24+
self.totalSamples = totalSamples
25+
self.asset = asset
26+
self.assetTrack = assetTrack
27+
}
28+
29+
public static func load(fromAudioURL audioURL: URL, completionHandler: @escaping (_ audioContext: FDAudioContext?) -> ()) {
30+
let asset = AVURLAsset(url: audioURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: NSNumber(value: true as Bool)])
31+
32+
guard let assetTrack = asset.tracks(withMediaType: AVMediaTypeAudio).first else {
33+
NSLog("FDWaveformView failed to load AVAssetTrack")
34+
completionHandler(nil)
35+
return
36+
}
37+
38+
asset.loadValuesAsynchronously(forKeys: ["duration"]) {
39+
var error: NSError?
40+
let status = asset.statusOfValue(forKey: "duration", error: &error)
41+
switch status {
42+
case .loaded:
43+
guard
44+
let audioFormatDesc = assetTrack.formatDescriptions.first,
45+
let asbd = CMAudioFormatDescriptionGetStreamBasicDescription(audioFormatDesc as! CMAudioFormatDescription) // TODO: Can this be safer?
46+
else { break }
47+
48+
let totalSamples = Int((asbd.pointee.mSampleRate) * Float64(asset.duration.value) / Float64(asset.duration.timescale))
49+
let audioContext = FDAudioContext(audioURL: audioURL, totalSamples: totalSamples, asset: asset, assetTrack: assetTrack)
50+
completionHandler(audioContext)
51+
return
52+
53+
case .failed, .cancelled, .loading, .unknown:
54+
print("FDWaveformView could not load asset: \(error?.localizedDescription ?? "Unknown error")")
55+
}
56+
57+
completionHandler(nil)
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)