Skip to content

Commit 01dd2f2

Browse files
committed
Add audio attributes for doument preview
1 parent a768550 commit 01dd2f2

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

CotEditor/Sources/Document Window/Content View/FilePreviewView.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ struct FilePreviewView: View {
7777
ImageAttributesView(attributes: attributes)
7878
case let attributes as MovieAttributes:
7979
MovieAttributesView(attributes: attributes)
80+
case let attributes as AudioAttributes:
81+
AudioAttributesView(attributes: attributes)
8082
default:
8183
EmptyView()
8284
}
@@ -165,6 +167,20 @@ struct MovieAttributesView: View {
165167
}
166168

167169

170+
struct AudioAttributesView: View {
171+
172+
var attributes: AudioAttributes
173+
174+
175+
var body: some View {
176+
177+
LabeledContent(String(localized: "Duration", table: "Document"),
178+
value: self.attributes.duration,
179+
format: .time(pattern: self.attributes.duration.naturalPattern))
180+
}
181+
}
182+
183+
168184
private extension CGSize {
169185

170186
/// The human-readable representation.

CotEditor/Sources/Document/PreviewDocument.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ protocol FileContentAttributes: Sendable, Equatable { }
7979
self.contentAttributes = attributes
8080
}
8181
}
82+
83+
} else if type.conforms(to: .audio) {
84+
Task {
85+
let attributes = try await AVAsset(url: url).audioAttributes
86+
87+
await MainActor.run {
88+
self.contentAttributes = attributes
89+
}
90+
}
8291
}
8392
}
8493

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//
2+
// AudioAttributes.swift
3+
//
4+
// CotEditor
5+
// https://coteditor.com
6+
//
7+
// Created by 1024jp on 2025-05-19.
8+
//
9+
// ---------------------------------------------------------------------------
10+
//
11+
// © 2025 1024jp
12+
//
13+
// Licensed under the Apache License, Version 2.0 (the "License");
14+
// you may not use this file except in compliance with the License.
15+
// You may obtain a copy of the License at
16+
//
17+
// https://www.apache.org/licenses/LICENSE-2.0
18+
//
19+
// Unless required by applicable law or agreed to in writing, software
20+
// distributed under the License is distributed on an "AS IS" BASIS,
21+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
// See the License for the specific language governing permissions and
23+
// limitations under the License.
24+
//
25+
26+
import AVFoundation
27+
28+
struct AudioAttributes: FileContentAttributes {
29+
30+
var duration: Duration
31+
}
32+
33+
34+
extension AVAsset {
35+
36+
final var audioAttributes: AudioAttributes {
37+
38+
get async throws {
39+
try await AudioAttributes(
40+
duration: .seconds(self.load(.duration).seconds)
41+
)
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)