最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - How to start picture in picture directly in app? - Stack Overflow

programmeradmin0浏览0评论

I have this simple code:

private func playVideo() {
    guard let videoURL = Bundle.main.url(
        forResource: "video",
        withExtension: "mp4"
    ) else {
        return
    }
        
    let avPlayerController = AVPlayerViewController()
    let player = AVPlayer(url: videoURL)
    avPlayerController.player = player
    avPlayerController.canStartPictureInPictureAutomaticallyFromInline = true
    present(avPlayerController, animated: true)
        
    avPlayerController.player?.play()
        
    let pipController = AVPictureInPictureController(
        playerLayer: .init(player: player)
    )
        
    pipController?.canStartPictureInPictureAutomaticallyFromInline = true
    pipController?.startPictureInPicture()
}

In the App Delegate:

try? AVAudioSession.sharedInstance().setCategory(.playback)
try? AVAudioSession.sharedInstance().setActive(true)

This starts effectively the picture in picture when the user leaves the app, and if he comes back by tapping the app icon, it stays running in the app. Now I would like to know if there is a way to directly start the picture-in-picture in the app, when a given view appears for example.

I have this simple code:

private func playVideo() {
    guard let videoURL = Bundle.main.url(
        forResource: "video",
        withExtension: "mp4"
    ) else {
        return
    }
        
    let avPlayerController = AVPlayerViewController()
    let player = AVPlayer(url: videoURL)
    avPlayerController.player = player
    avPlayerController.canStartPictureInPictureAutomaticallyFromInline = true
    present(avPlayerController, animated: true)
        
    avPlayerController.player?.play()
        
    let pipController = AVPictureInPictureController(
        playerLayer: .init(player: player)
    )
        
    pipController?.canStartPictureInPictureAutomaticallyFromInline = true
    pipController?.startPictureInPicture()
}

In the App Delegate:

try? AVAudioSession.sharedInstance().setCategory(.playback)
try? AVAudioSession.sharedInstance().setActive(true)

This starts effectively the picture in picture when the user leaves the app, and if he comes back by tapping the app icon, it stays running in the app. Now I would like to know if there is a way to directly start the picture-in-picture in the app, when a given view appears for example.

Share Improve this question edited Feb 4 at 18:49 HangarRash 15k5 gold badges19 silver badges55 bronze badges asked Feb 4 at 10:47 Another DudeAnother Dude 1,4515 gold badges21 silver badges41 bronze badges 1
  • You need wait for isPictureInPicturePossible get's true then with little delay call startPictureInPicture. Also layer that you pass to playerLayer should be in visible hierarchy. But you need get rid from AVPlayerViewController – Cy-4AH Commented Feb 4 at 15:14
Add a comment  | 

1 Answer 1

Reset to default -1

There is no picture-in-picture in the app. Whenever you apply AVPictureInPictureController, the system determines which UI to dipslay automatically when you're in background mode (by adding Background Modes in Capability). In this case is AVPlayerLayer, or whatever content of any view controller that inherits to AVPictureInPictureVideoCallViewController if you use this kind of PiP adapter.

So, if you want a kind of PiP within the app, you need to do it yourself. Something like implementing a custom view that sticks on your screen's edges in the foreground mode and then additionally a UIPanGestureRecognizer to be able to drag/drop this view.

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>