Skip to content

Commit 25201c2

Browse files
committed
Set viewport for WebM files
1 parent b4a5e96 commit 25201c2

File tree

4 files changed

+81
-35
lines changed

4 files changed

+81
-35
lines changed

previewer/PreviewViewController.swift

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ let kMinimumPeriod = 60 // Don't create snapshots spaced more closely than this
2020
let kWindowWidthThreshhold: CGFloat = 600 // Finder Column view max width = 560
2121
let kWindowHeightThreshhold: CGFloat = 160 // Get Info height = 128, QuickLook minimum window height = 180
2222

23+
enum PreviewType { case snapshot, webView, contactSheet }
24+
2325
// Window title helper
2426
func displayname(title: String, size: CGSize, duration: Int, channels: Int) -> String {
2527
var channelstring: String
@@ -85,9 +87,6 @@ class PreviewViewController: NSViewController, QLPreviewingController, NSCollect
8587
snapshot.layer!.backgroundColor = .black // CoreMedia previewer does this in Finder's Column & Gallery views
8688
sidebarCollection.backgroundColors = [.clear]
8789
sidebarCollection.register(NSNib(nibNamed: "SidebarItem", bundle: nil), forItemWithIdentifier: SidebarItem.identifier)
88-
webView.isHidden = true
89-
webView.underPageBackgroundColor = NSColor.clear
90-
webView.enclosingScrollView?.backgroundColor = NSColor.clear
9190
}
9291

9392
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
@@ -116,6 +115,20 @@ class PreviewViewController: NSViewController, QLPreviewingController, NSCollect
116115
}
117116
#endif
118117

118+
// Hide Views other than the one we want to show
119+
func setupPreview(_ previewType: PreviewType) {
120+
switch previewType {
121+
case .snapshot:
122+
sidebar.removeFromSuperview()
123+
webView.removeFromSuperview()
124+
case .webView:
125+
sidebar.removeFromSuperview()
126+
snapshot.removeFromSuperview()
127+
case .contactSheet:
128+
webView.removeFromSuperview()
129+
}
130+
}
131+
119132
func preparePreviewOfSearchableItem(identifier: String, queryString: String?) async throws {
120133
// Implement this method and set QLSupportsSearchableItems to YES in the Info.plist of the extension if you support CoreSpotlight.
121134
#if DEBUG
@@ -156,19 +169,33 @@ class PreviewViewController: NSViewController, QLPreviewingController, NSCollect
156169
snapshotSize = snapshotter.previewSize
157170
let videoCodec = snapshotter.videoCodec
158171

159-
// if extension of the file is webm, use WebView to load it
160-
if url.pathExtension == "webm" && (videoCodec == "vp8" || videoCodec == "vp9") {
161-
preferredContentSize = snapshotSize
162-
webView.isHidden = false
163-
webView.loadFileURL(url, allowingReadAccessTo: url)
164-
return
165-
}
166172
// Should we prepare a full-sized (QLPreviewViewStyle.normal) preview for e.g. Finder's QuickLook
167173
// or a single image (QLPreviewViewStyle.compact) for e.g. Finder's Column view and Get Info panel.
168174
// Don't know how to get hold of QLPreviewViewStyle from here, so use window size to decide
169175
if view.frame.width < kWindowWidthThreshhold || view.frame.height < kWindowHeightThreshhold {
170176
// QLPreviewViewStyle.compact
171-
if let coverart = snapshotter.newCoverArt(with: view.frame.width < kWindowHeightThreshhold ? .thumbnail : .default) {
177+
178+
// use WebView to load WEBM files
179+
if url.pathExtension.caseInsensitiveCompare("webm") == .orderedSame && (videoCodec == "vp8" || videoCodec == "vp9") {
180+
// Fit to width
181+
let size = NSSize(width: view.frame.width, height: view.frame.width * snapshotSize.height / snapshotSize.width)
182+
setupPreview(.webView)
183+
webView.loadFileURL(url, allowingReadAccessTo: url)
184+
webView.loadHTMLString(
185+
"""
186+
<html>
187+
<meta name="viewport" content="width=\(size.width), height=\(size.height)" />
188+
<body style="background-color:black;margin:0;padding:0;">
189+
<video controls width="width=\(size.width)" height="\(size.height)">
190+
<source src="\(url.lastPathComponent)" type="video/webm" />
191+
</body>
192+
</html>
193+
""", baseURL: url.deletingLastPathComponent())
194+
preferredContentSize = size
195+
return
196+
} else if let coverart = snapshotter.newCoverArt(
197+
with: view.frame.width < kWindowHeightThreshhold ? .thumbnail : .default)
198+
{
172199
snapshotSize = CGSize(width: coverart.width, height: coverart.height)
173200
snapshot.image = NSImage(cgImage: coverart, size: .zero)
174201
} else {
@@ -206,7 +233,7 @@ class PreviewViewController: NSViewController, QLPreviewingController, NSCollect
206233
userInfo: [NSLocalizedFailureReasonErrorKey: "Can't supply anything"])
207234
}
208235
}
209-
sidebar.removeFromSuperview() // Don't want sidebar
236+
setupPreview(.snapshot)
210237
snapshot.frame = NSRect(origin: CGPointZero, size: view.frame.size)
211238
// Fit to width
212239
preferredContentSize = NSSize(
@@ -223,6 +250,24 @@ class PreviewViewController: NSViewController, QLPreviewingController, NSCollect
223250
title: snapshotter.title ?? url.lastPathComponent, size: snapshotter.displaySize, duration: snapshotter.duration,
224251
channels: Int(snapshotter.channels))
225252

253+
// use WebView to load WEBM files
254+
if url.pathExtension.caseInsensitiveCompare("webm") == .orderedSame && (videoCodec == "vp8" || videoCodec == "vp9") {
255+
setupPreview(.webView)
256+
webView.loadFileURL(url, allowingReadAccessTo: url)
257+
webView.loadHTMLString(
258+
"""
259+
<html>
260+
<meta name="viewport" content="width=\(snapshotSize.width), height=\(snapshotSize.height)" />
261+
<body style="background-color:black;margin:0;padding:0;">
262+
<video controls autoplay width="width=\(snapshotSize.width)" height="\(snapshotSize.height)">
263+
<source src="\(url.lastPathComponent)" type="video/webm" />
264+
</body>
265+
</html>
266+
""", baseURL: url.deletingLastPathComponent())
267+
preferredContentSize = NSSize(width: snapshotSize.width, height: snapshotSize.height)
268+
return
269+
}
270+
226271
var imageCount = 0
227272

228273
if snapshotter.pictures > 0 {
@@ -278,11 +323,12 @@ class PreviewViewController: NSViewController, QLPreviewingController, NSCollect
278323
domain: "uk.org.marginal.qlvideo", code: -1, userInfo: [NSLocalizedFailureReasonErrorKey: "Can't supply anything"]
279324
)
280325
} else if images.count == 1 {
326+
setupPreview(.snapshot)
281327
snapshot.image = images[0]
282-
sidebar.removeFromSuperview() // no need for sidebar
283328
snapshot.frame = NSRect(origin: CGPointZero, size: view.frame.size)
284329
preferredContentSize = snapshotSize
285330
} else {
331+
setupPreview(.contactSheet)
286332
snapshot.image = images[0]
287333
if snapshotSize.width / snapshotSize.height > 4.0 / 3.0 {
288334
(sidebarCollection.collectionViewLayout as! NSCollectionViewFlowLayout).itemSize = CGSize(

previewer/PreviewViewController.xib

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
<customView wantsLayer="YES" translatesAutoresizingMaskIntoConstraints="NO" id="c22-O7-iKe" userLabel="Preview View">
2121
<rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
2222
<subviews>
23+
<wkWebView wantsLayer="YES" allowsBackForwardNavigationGestures="YES" allowsMagnification="YES" id="AS2-Sv-Of1">
24+
<rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
25+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
26+
<wkWebViewConfiguration key="configuration">
27+
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" audio="YES" video="YES"/>
28+
<wkPreferences key="preferences"/>
29+
</wkWebViewConfiguration>
30+
</wkWebView>
2331
<scrollView autoresizesSubviews="NO" wantsLayer="YES" fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UG7-nJ-TAy">
2432
<rect key="frame" x="0.0" y="0.0" width="180" height="600"/>
2533
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" heightSizable="YES"/>
@@ -57,14 +65,6 @@
5765
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
5866
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" id="d9s-ZW-k0c"/>
5967
</imageView>
60-
<wkWebView wantsLayer="YES" allowsLinkPreview="NO" allowsMagnification="YES" id="AS2-Sv-Of1">
61-
<rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
62-
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
63-
<wkWebViewConfiguration key="configuration">
64-
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" video="YES"/>
65-
<wkPreferences key="preferences"/>
66-
</wkWebViewConfiguration>
67-
</wkWebView>
6868
</subviews>
6969
<point key="canvasLocation" x="139" y="-36"/>
7070
</customView>

previewer/Snapshotter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ typedef NS_ENUM(NSInteger, CoverArtMode)
6060
@property (nonatomic,assign,readonly) CGSize displaySize;
6161
@property (nonatomic,assign,readonly) CGSize previewSize;
6262
@property (nonatomic,assign,readonly) NSInteger duration;
63-
@property (nonatomic,retain,readonly) NSString *title;
6463
@property (nonatomic,retain,readonly,nullable) NSString *videoCodec;
64+
@property (nonatomic,retain,readonly) NSString *title;
6565

6666
@end

previewer/Snapshotter.m

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,19 @@ - (NSInteger) duration
249249
return fmt_ctx->duration > 0 ? (fmt_ctx->duration / AV_TIME_BASE) : 0; // We're not interested in sub-second accuracy
250250
}
251251

252+
- (NSString*) videoCodec
253+
{
254+
if (video_stream_idx < 0 || !fmt_ctx)
255+
return nil;
256+
257+
AVStream *s = fmt_ctx->streams[video_stream_idx];
258+
AVCodecParameters *params = s->codecpar;
259+
if (!params)
260+
return nil;
261+
enum AVCodecID codecID = params->codec_id;
262+
return @(avcodec_get_name(codecID));
263+
}
264+
252265
// Gets cover art if available, or nil.
253266
- (CGImageRef) newCoverArtWithMode:(CoverArtMode)mode
254267
{
@@ -603,17 +616,4 @@ - (CFDataRef) newPNGWithSize:(CGSize)size atTime:(NSInteger)seconds;
603616
return data;
604617
}
605618

606-
- (NSString*) videoCodec
607-
{
608-
if (video_stream_idx < 0 || !fmt_ctx)
609-
return nil;
610-
611-
AVStream *s = fmt_ctx->streams[video_stream_idx];
612-
AVCodecParameters *params = s->codecpar;
613-
if (!params)
614-
return nil;
615-
enum AVCodecID codecID = params->codec_id;
616-
return @(avcodec_get_name(codecID));
617-
}
618-
619619
@end

0 commit comments

Comments
 (0)