ios swift畫中畫技術嘗試

繼上篇:iOS swift 后臺運行應用嘗試失敗-CSDN博客

為什么想到畫中畫,起初是看到后臺模式里有一個picture in picture,去了解了后發現這個就是小窗口視頻播放,方便用戶執行多任務。看小窗口視頻的同時,可以作其他的事情。

畫中畫功能在20世紀80年代開始在電視機中應用,使得用戶可以在一個屏幕上同時觀看兩個頻道的內容。?

這個技術在安卓里已經非常普遍了。各種視頻內容網站都有類似功能。

而蘋果支持畫中畫是在ios14已經開始支持。目前在使用的大多數機型,比如iphone 8p,升級系統后可到ios16.7,都能支持畫中畫技術。

后臺任務蘋果管理太嚴格,不好搞,那么使用畫中畫這種技術,直接做成多任務,這樣也是另一條可以嘗試的路徑。

1、標準PIP使用

首先,標準寫法是采用AVPlayer,輸入url需要是MP4等視頻文件,如果是加密后的網址,無法播放,比如b站的網址。

創建AVPlayer,使用AVPlayerLayer來初始化AVPictureInPictrueController。

        // 創建 AVPlayer 對象let videoURL = URL(string: "https://media.w3.org/2010/05/sintel/trailer.mp4")!player = AVPlayer(url: videoURL)// 創建 AVPlayerLayer 并添加到視圖層上playerLayer = AVPlayerLayer(player: player)playerLayer.frame = view.boundsview.layer.addSublayer(playerLayer)// 設置畫中畫控制器pipController = AVPictureInPictureController(playerLayer: playerLayer)pipController.delegate = selfplayer.play()   // 直接播放

按home鍵退出,就會自動啟動小窗口繼續播放視頻。

這里有一個坑,需要初始化音頻,否則播放mp4無聲音,且畫中畫也不會觸發。

    do {// 設置AVAudioSession為后臺模式try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)try AVAudioSession.sharedInstance().setActive(true)} catch {print("無法設置AVAudioSession: \(error)")}

視頻畫中畫,iphone 8p

2、攝像頭預覽

攝像頭捕捉并預覽,這個算法也很容易找到,使用AVCaptureSession

func setupCamera(forgroundFlag: Bool, view: UIView) {farView = viewflag = forgroundFlagcaptureSession = AVCaptureSession()captureSession?.beginConfiguration()captureSession?.sessionPreset = .highguard let captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) else {print("No front camera available")return}guard let input = try? AVCaptureDeviceInput(device: captureDevice) else {print("Unable to access front camera")return}captureSession!.addInput(input)videoOutput = AVCaptureVideoDataOutput()videoOutput?.automaticallyConfiguresOutputBufferDimensions = truevideoOutput!.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))captureSession!.addOutput(videoOutput!)if (forgroundFlag) {videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)guard let preLayer = videoPreviewLayer else { return }preLayer.frame = view.frameview.layer.addSublayer(preLayer)// 設置 UILabel 的屬性label = UILabel()label!.text = "Hello, Swift!" // 設置文本內容label!.textColor = UIColor.systemBlue // 設置文本顏色label!.font = UIFont.systemFont(ofSize: 20) // 設置字體和大小label!.textAlignment = .left // 設置文本對齊方式label!.numberOfLines = 0 // 設置行數,0表示自動換行// 設置 UILabel 的位置和大小label!.frame = CGRect(x: 8, y: 20, width: 200, height: 30)}captureSession?.commitConfiguration()}

AVCaptureSession輸出的是AVCaptureVideoPreviewLayer,這個layer無法直接用來初始化AVPictureInPictrueController。

3、攝像頭輸出PIP

swift代碼在標準案例上實現都很簡潔,但要自定義實現一些功能時,就會發現材料很難找。

比如怎樣把攝像頭預覽與PIP結合。

深度搜索AI給出了一個結果,看上去好像可以,實踐下來編輯都不能通過。但是它給出了一個提示,就是AVSampleBufferDisplayLayer。

這里吐槽下AI,最喜歡把不可用的東西包裝成很好看的樣子,在技術搜索方面,某些時候還不如原始的搜索引擎來得方便。

搜索AVCaptureVideoPreviewLayer轉為AVSampleBufferDisplayLayer,也有方法,但是算法看上去稍顯復雜。

官方文檔Adopting Picture in Picture in a Custom Player | Apple Developer Documentation里也提到了可以使用AVSampleBufferDisplayLayer來初始化PIPController。

網上另一篇文章,說在捕獲處理接口里,還有一個視頻數據

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)

CMSampleBuffer可以直接轉為AVSampleBufferDisplayLayer,使用enqueu接口,如下:

    func setupSampleBufferDisplayLayer() {sampleBufferDisplayLayer = AVSampleBufferDisplayLayer()sampleBufferDisplayLayer.frame = view.boundssampleBufferDisplayLayer.videoGravity = .resizeAspectview.layer.addSublayer(sampleBufferDisplayLayer)}func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
。。。。。。        if (sampleBufferDisplayLayer.status == AVQueuedSampleBufferRenderingStatus.failed) {sampleBufferDisplayLayer.flush() // 異常處理}sampleBufferDisplayLayer.enqueue(sampleBuffer)
。。。。。。

這樣整個流程就能打通了。

通過AVSampleBufferDisplayLayer,可以用任何視頻流來初始化AVPictureInPictureController。

    private func setupPiPController() {guard AVPictureInPictureController.isPictureInPictureSupported() else {print("Picture in Picture is not supported on this device")return}print("support pip!!!")if pipController == nil {pipController = AVPictureInPictureController(contentSource: .init(sampleBufferDisplayLayer: sampleBufferDisplayLayer, playbackDelegate: self))}if let pipController = pipController {pipController.delegate = selfif pipController.isPictureInPicturePossible {pipController.startPictureInPicture()}}}

4、攝像頭多任務需要硬件支持

前面生成的工程,在iphone 8p上測試效果如下,進入畫中畫模式時,在1s以內視頻捕獲就停止了。

攝像頭畫中畫,iphone 8p

原因在于蘋果對攝像頭硬件管理非常嚴格,攝像頭開小窗口,那么用戶就可能用攝像頭打開另一個任務,意味著攝像頭需要支持多任務。

參考官方說明:

增加代碼檢查如下:

    func setupCamera(forgroundFlag: Bool, view: UIView) {
。。。。。。        guard let tempcap = captureSession else { return }if (tempcap.isMultitaskingCameraAccessSupported) {print("camera supp multitask")// Enable use of the camera in multitasking modes.captureSession?.isMultitaskingCameraAccessEnabled = true} else {print("camera not supp multitask")}captureSession?.commitConfiguration()}

從調試打印來看,iphone 8p的攝像頭不支持多任務。

根據AI查詢結果,可能需要iphone 12以上的機型才能支持攝像頭多任務。

對于AI返回結果比較存疑,因為多次返回的結果可能會不一樣。比如iphone XR,有的說支持,有的說不支持。

參考另外的官方文章,視頻通話、直播畫中畫都是一樣的。

Adopting Picture in Picture for video calls | Apple Developer Documentation

因為本人手上只有iphone 8p,沒有其他新機型,所以后面的調試驗證沒法繼續下去了。在沒有訂單推動情況下,也不會投入了。

如果有相關項目需求的,可以找我咨詢合作。
? ? ?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67635.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67635.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67635.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenAI推出o3-mini推理模型,首次免費開放,性能超越o1,AIME測試準確率高達87.3%

OpenAI在2025年初推出了一款新的推理模型o3-mini,這款模型標志著公司在提升性能的同時也降低了成本,并且首次向免費用戶提供訪問權限。o3-mini是OpenAI推理系列中最新、最具成本效益的模型,在科學、數學、編程等領域的性能顯著超越了之前的o1…

人生不止于職業發展

0 你的問題,我知道! 工作意義是啥?職業發展在人生啥角色? 1 工作意義 農村人努力學習考上大學,得好工作,為逃離同村同齡人十幾歲就工廠打工命運,過不凡人生,實現改命的唯一途徑。…

【算法設計與分析】實驗3:動態規劃—最長公共子序列

目錄 一、實驗目的 二、實驗環境 三、實驗內容 四、核心代碼 五、記錄與處理 六、思考與總結 七、完整報告和成果文件提取鏈接 一、實驗目的 掌握動態規劃求解問題的思想;針對不同的問題,會利用動態規劃進行設計求解以及時間復雜度分析&#xff0…

動手學圖神經網絡(3):利用圖神經網絡進行節點分類 從理論到實踐

利用圖神經網絡進行節點分類:從理論到實踐 前言 在之前的學習中,大家對圖神經網絡有了初步的了解。本次教程將深入探討如何運用圖神經網絡(GNNs)來解決節點分類問題。在節點分類任務里,大家往往僅掌握少量節點的真實標簽,卻要推斷出其余所有節點的標簽,這屬于歸納式學…

單片機串口打印printf函數顯示內容(固件庫開發)

1.hal_usart.c 文件 #include <stdio.h> #include "hal_usart.h" #include "stm32F10x.h"//**要根據 使用的是哪個串口 對應修改 串口號 eg&#xff1a;USART1** void USART_PUTC(char ch) {/* 等待數據寄存器為空 */while((USART1->SR & …

網關登錄校驗

網關登錄校驗 單體架構時我們只需要完成一次用戶登錄、身份校驗&#xff0c;就可以在所有業務中獲取到用戶信息。而微服務拆分后&#xff0c;每個微服務都獨立部署&#xff0c;不再共享數據。也就意味著每個微服務都需要做登錄校驗&#xff0c;這顯然不可取。 鑒權思路分析 …

wxwidgets直接獲取系統圖標,效果類似QFileIconProvider

目前只做了windows版本&#xff0c;用法類似QFileIconProvider // 頭文件 #ifndef WXFILEICONPROVIDER_H #define WXFILEICONPROVIDER_H#include <wx/wx.h> #include <wx/icon.h> #include <wx/image.h> #include <wx/bmpcbox.h> // Include for wxB…

我的創作紀念日——成為創作者的 第365天(1年)

機緣 考研的結果讓我感到一陣絕望&#xff0c;就像單片機突然死機一樣&#xff0c;所有的努力像是被一場意外的中斷指令打亂了邏輯流程。曾經本科時因為競賽拿了一堆獎&#xff0c;內心充滿虛榮心和成就感&#xff0c;總覺得自己是一個“天選之子”&#xff0c;但考研的失利卻像…

React 封裝高階組件 做路由權限控制

React 高階組件是什么 官方解釋∶ 高階組件&#xff08;HOC&#xff09;是 React 中用于復用組件邏輯的一種高級技巧。HOC 自身不是 React API 的一部分&#xff0c;它是一種基于 React 的組合特性而形成的設計模式。 高階組件&#xff08;HOC&#xff09;就是一個函數&…

【玩轉全棧】--創建一個自己的vue項目

目錄 vue介紹 創建vue項目 vue頁面介紹 element-plus組件庫 啟動項目 vue介紹 Vue.js 是一款輕量級、易于上手的前端 JavaScript 框架&#xff0c;旨在簡化用戶界面的開發。它采用了響應式數據綁定和組件化的設計理念&#xff0c;使得開發者可以通過聲明式的方式輕松管理數據和…

DS并查集(17)

文章目錄 前言一、何為并查集&#xff1f;二、并查集的實現&#xff1f;并查集的初始化查找元素所在的集合判斷兩個元素是否在同一個集合合并兩個元素所在的集合獲取并查集中集合的個數并查集的路徑壓縮 三、來兩道題練練手&#xff1f;省份的數量等式方程的可滿足性 總結 前言…

Appium介紹

在使用不同版本的Appium包進行自動化測試時&#xff0c;出現警告問題可能是由于版本不兼容、配置不正確等原因導致的。下面將詳細介紹解決這些問題的步驟&#xff0c;確保模擬器能夠正常啟動&#xff0c;并能在Appium查看器中同步顯示。 1. 環境準備 首先&#xff0c;確保你已…

minimind - 從零開始訓練小型語言模型

大語言模型&#xff08;LLM&#xff09;領域&#xff0c;如 GPT、LLaMA、GLM 等&#xff0c;雖然它們效果驚艷&#xff0c; 但動輒10 Bilion龐大的模型參數個人設備顯存遠不夠訓練&#xff0c;甚至推理困難。 幾乎所有人都不會只滿足于用Lora等方案fine-tuing大模型學會一些新的…

【C++動態規劃 離散化】1626. 無矛盾的最佳球隊|2027

本文涉及知識點 C動態規劃 離散化 LeetCode1626. 無矛盾的最佳球隊 假設你是球隊的經理。對于即將到來的錦標賽&#xff0c;你想組合一支總體得分最高的球隊。球隊的得分是球隊中所有球員的分數 總和 。 然而&#xff0c;球隊中的矛盾會限制球員的發揮&#xff0c;所以必須選…

CSS 值和單位詳解:從基礎到實戰

CSS 值和單位詳解&#xff1a;從基礎到實戰 1. 什么是 CSS 的值&#xff1f;示例代碼&#xff1a;使用顏色關鍵字和 RGB 函數 2. 數字、長度和百分比2.1 長度單位絕對長度單位相對長度單位 2.2 百分比 3. 顏色3.1 顏色關鍵字3.2 十六進制 RGB 值3.3 RGB 和 RGBA 值3.4 HSL 和 H…

Privacy Eraser,電腦隱私的終極清除者

Privacy Eraser 是一款專為保護用戶隱私而設計的全能型軟件&#xff0c;它不僅能夠深度清理計算機中的各類隱私數據&#xff0c;還提供了多種系統優化工具&#xff0c;幫助用戶提升設備的整體性能。通過這款軟件&#xff0c;用戶可以輕松清除瀏覽器歷史記錄、緩存文件、Cookie、…

Android 啟動流程

一 Bootloader 階段 在嵌入式系統中&#xff0c;Bootloader的引導過程與傳統的PC環境有所不同&#xff0c;主要是因為嵌入式系統的硬件配置和應用場景更加多樣化。以下是嵌入式系統中Bootloader被引導的一般流程&#xff1a; 1. 硬件復位 當嵌入式設備上電或復位時&#xff…

【數據結構與算法】AVL樹的插入與刪除實現詳解

文章目錄 前言Ⅰ. AVL樹的定義Ⅱ. AVL樹節點的定義Ⅲ. AVL樹的插入Insert一、節點的插入二、插入的旋轉① 新節點插入較高左子樹的左側&#xff08;左左&#xff09;&#xff1a;右單旋② 新節點插入較高右子樹的右側&#xff08;右右&#xff09;&#xff1a;左單旋③ 新節點插…

SCRM開發為企業提供全面客戶管理解決方案與創新實踐分享

內容概要 在當今的商業環境中&#xff0c;客戶關系管理&#xff08;CRM&#xff09;變得越來越重要。而SCRM&#xff08;社交客戶關系管理&#xff09;作為一種新興的解決方案&#xff0c;正在幫助企業徹底改變與客戶的互動方式。快鯨SCRM是一個引人注目的工具&#xff0c;它通…

AI應用部署——streamlit

如何把項目部署到一個具有公網ip地址的服務器上&#xff0c;讓他人看到&#xff1f; 可以利用 streamlit 的社區云免費部署 1、生成requirements.txt文件 終端輸入pip freeze > requirements.txt即可 requirements.txt里既包括自己安裝過的庫&#xff0c;也包括這些庫的…