Skip to content

Commit f23df2d

Browse files
committed
feat: add take local snapshot to iOS
1 parent 0def999 commit f23df2d

4 files changed

Lines changed: 73 additions & 12 deletions

File tree

iOS/APIExample/APIExample/Common/AgoraExtension.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,3 +339,15 @@ extension AgoraApplicationScenarioType {
339339
}
340340
}
341341
}
342+
343+
extension AgoraVideoModulePosition {
344+
func description() -> String {
345+
switch self {
346+
case .postCapture: return "Post Capture".localized
347+
case .preRenderer: return "PreRenderer".localized
348+
case .preEncoder: return "PreEncoder".localized
349+
case .postCaptureOrigin: return "Post Capture Origin".localized
350+
@unknown default: return ""
351+
}
352+
}
353+
}

iOS/APIExample/APIExample/Examples/Advanced/LiveStreaming/Base.lproj/LiveStreaming.storyboard

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -318,29 +318,31 @@
318318
<view alpha="0.80000001192092896" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="i5U-ta-1hj" userLabel="watermark">
319319
<rect key="frame" x="20" y="524.5" width="108" height="35"/>
320320
<subviews>
321-
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="水印" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nSq-Vu-o9H">
321+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="水印" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nSq-Vu-o9H">
322322
<rect key="frame" x="8" y="-2" width="37" height="40"/>
323-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
324323
<fontDescription key="fontDescription" type="system" pointSize="16"/>
325324
<color key="textColor" name="btnPanelForeground"/>
326325
<nil key="highlightedColor"/>
327326
</label>
328-
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="dpb-rd-5hC">
329-
<rect key="frame" x="53" y="2" width="49" height="31"/>
330-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
327+
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="dpb-rd-5hC">
328+
<rect key="frame" x="53" y="2" width="51" height="31"/>
331329
<connections>
332330
<action selector="onTapWatermarkSwitch:" destination="jxp-ZN-2yG" eventType="valueChanged" id="KnA-tb-0qI"/>
333331
</connections>
334332
</switch>
335333
</subviews>
336334
<color key="backgroundColor" name="btnPanelBackground"/>
337335
<constraints>
336+
<constraint firstItem="dpb-rd-5hC" firstAttribute="centerY" secondItem="i5U-ta-1hj" secondAttribute="centerY" id="B66-bx-sex"/>
337+
<constraint firstItem="dpb-rd-5hC" firstAttribute="leading" secondItem="nSq-Vu-o9H" secondAttribute="trailing" constant="8" symbolic="YES" id="Pbf-Mg-Qrk"/>
338+
<constraint firstItem="dpb-rd-5hC" firstAttribute="centerY" secondItem="nSq-Vu-o9H" secondAttribute="centerY" id="Rmf-dG-Yo9"/>
339+
<constraint firstAttribute="trailing" secondItem="dpb-rd-5hC" secondAttribute="trailing" constant="6" id="YTX-EX-a9o"/>
338340
<constraint firstAttribute="height" constant="35" id="YY8-rd-73l"/>
339341
<constraint firstAttribute="width" constant="108" id="hUe-Ww-F49"/>
340342
</constraints>
341343
</view>
342344
<view alpha="0.80000001192092896" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sOi-ZR-6Oj" userLabel="dualStream">
343-
<rect key="frame" x="141" y="551" width="146" height="55"/>
345+
<rect key="frame" x="229" y="551" width="146" height="55"/>
344346
<subviews>
345347
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="大小流" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="auZ-cF-RlC">
346348
<rect key="frame" x="8" y="6" width="51" height="27"/>
@@ -371,21 +373,41 @@
371373
</constraints>
372374
</view>
373375
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="w4q-aT-JBc">
374-
<rect key="frame" x="20" y="569.5" width="80" height="34.5"/>
376+
<rect key="frame" x="20" y="569.5" width="93.5" height="34.5"/>
375377
<color key="backgroundColor" name="btnPanelBackground"/>
376378
<constraints>
377379
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="Xdc-MD-QxT"/>
378380
</constraints>
379381
<state key="normal" title="Button"/>
380-
<buttonConfiguration key="configuration" style="plain" title="截图" cornerStyle="fixed">
382+
<buttonConfiguration key="configuration" style="plain" title="本地截图" cornerStyle="fixed">
383+
<backgroundConfiguration key="background" cornerRadius="5">
384+
<color key="backgroundColor" name="btnPanelBackground"/>
385+
<color key="strokeColor" name="btnPanelBackground"/>
386+
</backgroundConfiguration>
387+
<color key="baseForegroundColor" name="btnPanelForeground"/>
388+
</buttonConfiguration>
389+
<connections>
390+
<action selector="onTakeLocalSnapshot:" destination="jxp-ZN-2yG" eventType="touchUpInside" id="GB4-SP-Qs4"/>
391+
</connections>
392+
</button>
393+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lpn-6Z-VV3">
394+
<rect key="frame" x="127" y="569" width="93.5" height="35"/>
395+
<color key="backgroundColor" name="btnPanelBackground"/>
396+
<constraints>
397+
<constraint firstAttribute="height" constant="35" id="EJL-Hg-zEY"/>
398+
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="VAQ-sf-npV"/>
399+
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="35" id="gUE-ju-pS0"/>
400+
</constraints>
401+
<state key="normal" title="Button"/>
402+
<buttonConfiguration key="configuration" style="plain" title="远端截图" cornerStyle="fixed">
381403
<backgroundConfiguration key="background" cornerRadius="5">
382404
<color key="backgroundColor" name="btnPanelBackground"/>
383405
<color key="strokeColor" name="btnPanelBackground"/>
384406
</backgroundConfiguration>
385407
<color key="baseForegroundColor" name="btnPanelForeground"/>
386408
</buttonConfiguration>
387409
<connections>
388-
<action selector="onTakeSnapshot:" destination="jxp-ZN-2yG" eventType="touchUpInside" id="kRb-DS-stE"/>
410+
<action selector="onTakeSnapshot:" destination="jxp-ZN-2yG" eventType="touchUpInside" id="ez8-p0-3uz"/>
389411
</connections>
390412
</button>
391413
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wts-5Z-p7a" userLabel="UltraLowLatency">
@@ -467,6 +489,7 @@
467489
<constraint firstItem="sOi-ZR-6Oj" firstAttribute="top" secondItem="b7R-QN-CCh" secondAttribute="bottom" constant="45" id="Fn8-02-ePb"/>
468490
<constraint firstItem="w4q-aT-JBc" firstAttribute="top" secondItem="i5U-ta-1hj" secondAttribute="bottom" constant="10" id="GpK-P5-Dz2"/>
469491
<constraint firstItem="Uwe-Fi-04a" firstAttribute="top" secondItem="Wts-5Z-p7a" secondAttribute="bottom" constant="10" id="JJa-xD-z27"/>
492+
<constraint firstItem="lpn-6Z-VV3" firstAttribute="leading" secondItem="w4q-aT-JBc" secondAttribute="trailing" constant="13.5" id="JOL-0B-Kgk"/>
470493
<constraint firstItem="dZm-Rf-imt" firstAttribute="leading" secondItem="v58-rP-HKa" secondAttribute="trailing" constant="10.5" id="LaR-vk-DTf"/>
471494
<constraint firstItem="q9v-1n-ZYf" firstAttribute="leading" secondItem="CeS-QQ-Djo" secondAttribute="leading" id="LsZ-af-6Wt"/>
472495
<constraint firstItem="q9v-1n-ZYf" firstAttribute="leading" secondItem="UFF-wU-Wze" secondAttribute="trailing" constant="-323" id="M4O-C8-oP4"/>
@@ -486,10 +509,11 @@
486509
<constraint firstItem="CN0-n0-1Gh" firstAttribute="top" secondItem="v58-rP-HKa" secondAttribute="bottom" constant="10" id="iRF-aj-uoa"/>
487510
<constraint firstItem="CeS-QQ-Djo" firstAttribute="trailing" secondItem="q9v-1n-ZYf" secondAttribute="trailing" id="isT-Rq-5PH"/>
488511
<constraint firstItem="sOi-ZR-6Oj" firstAttribute="top" secondItem="eGT-sd-I3g" secondAttribute="bottom" constant="3" id="ixF-7d-I3g"/>
489-
<constraint firstItem="sOi-ZR-6Oj" firstAttribute="leading" secondItem="w4q-aT-JBc" secondAttribute="trailing" constant="41" id="jKl-x3-P12"/>
490512
<constraint firstItem="CeS-QQ-Djo" firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="w4q-aT-JBc" secondAttribute="trailing" symbolic="YES" id="koD-0t-Wh7"/>
491513
<constraint firstItem="v58-rP-HKa" firstAttribute="leading" secondItem="CeS-QQ-Djo" secondAttribute="leading" constant="21" id="rjz-Va-GOW"/>
492514
<constraint firstItem="CeS-QQ-Djo" firstAttribute="trailing" secondItem="pha-4w-IfR" secondAttribute="trailing" constant="21" id="sLP-Ue-h7l"/>
515+
<constraint firstItem="lpn-6Z-VV3" firstAttribute="top" secondItem="i5U-ta-1hj" secondAttribute="bottom" constant="9.5" id="stx-ZD-gMQ"/>
516+
<constraint firstItem="sOi-ZR-6Oj" firstAttribute="leading" secondItem="lpn-6Z-VV3" secondAttribute="trailing" constant="8.5" id="svH-es-NYs"/>
493517
<constraint firstItem="CeS-QQ-Djo" firstAttribute="trailing" secondItem="eGT-sd-I3g" secondAttribute="trailing" constant="90" id="t2I-pH-4sJ"/>
494518
<constraint firstItem="tOf-AP-HSe" firstAttribute="top" secondItem="UFF-wU-Wze" secondAttribute="bottom" constant="12" id="tAF-9V-ijT"/>
495519
<constraint firstItem="Uwe-Fi-04a" firstAttribute="top" secondItem="Wts-5Z-p7a" secondAttribute="bottom" constant="10" id="wl5-PM-CyG"/>

iOS/APIExample/APIExample/Examples/Advanced/LiveStreaming/LiveStreaming.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ class LiveStreamingEntry: UIViewController {
144144
guard let self = self else { return }
145145
let idx = pickerView?.dataArray?.firstIndex(where: { $0 == key}) ?? 0
146146
let type = AgoraApplicationScenarioType(rawValue: idx) ?? .applicationGeneralScenario
147-
self.agoraKit.setVideoScenario(type)
147+
let ret = self.agoraKit.setVideoScenario(type)
148+
print("setVideoScenario[\(type.rawValue)] ret = \(ret)")
148149
self.videoScenarioButton?.setTitle(key, for: .normal)
149150
}
150151
}
@@ -458,6 +459,29 @@ class LiveStreamingMain: BaseViewController {
458459
agoraKit.takeSnapshot(Int(remoteUid), filePath: path)
459460
showAlert(title: "Screenshot successful".localized, message: path)
460461
}
462+
463+
@IBAction func onTakeLocalSnapshot(_ sender: Any) {
464+
let pickerView = PickerView()
465+
let values: [AgoraVideoModulePosition] = [
466+
// .postCapture,
467+
.preRenderer,
468+
.preEncoder,
469+
.postCaptureOrigin
470+
]
471+
pickerView.dataArray = values.map({ $0.description()})
472+
AlertManager.show(view: pickerView, alertPostion: .bottom)
473+
pickerView.pickerViewSelectedValueClosure = { [weak self, weak pickerView] key in
474+
guard let self = self else { return }
475+
let idx = pickerView?.dataArray?.firstIndex(where: { $0 == key}) ?? 0
476+
let position = values[idx]
477+
let config = AgoraSnapshotConfig()
478+
config.position = position
479+
config.filePath = NSTemporaryDirectory().appending("local_\(position.rawValue).png")
480+
let ret = agoraKit.takeSnapshotWithConfig(0, config: config)
481+
print("takeSnapshot ret: \(ret) path: \(config.filePath ?? "")")
482+
showAlert(title: "Screenshot successful".localized, message: config.filePath ?? "")
483+
}
484+
}
461485
@IBAction func onTapForegroundVideo(_ sender: UIGestureRecognizer) {
462486
isLocalVideoForeground = !isLocalVideoForeground
463487
let localVideoCanvas = AgoraRtcVideoCanvas()

iOS/APIExample/APIExample/Examples/Advanced/LiveStreaming/zh-Hans.lproj/LiveStreaming.strings

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010
/* Class = "UIButton"; normalTitle = "Join"; ObjectID = "kbN-ZR-nNn"; */
1111
"kbN-ZR-nNn.normalTitle" = "加入频道";
12-
"w4q-aT-JBc.normalTitle" = "截图";
12+
"w4q-aT-JBc.normalTitle" = "本地截图";
13+
"lpn-6Z-VV3.normalTitle" = "远端截图";
1314

1415
"ohV-am-Acd.text" = "首帧出图";
1516

0 commit comments

Comments
 (0)