我在ios设备和模拟器中播放视频内容时遇到了一些麻烦.
目标:从这里给出的在线资源流的视频:
使用HLS公共视频流使用AVPlayerViewController,只是为了了解它是如何工作的.
这始终导致没有抛出错误,但视图控制器向我展示了这个视图.
我决定退后一步测试一个本地资源,所以我在quicktime(.m4v)中拍摄了一个短屏捕获并将其保存到项目中.这导致完全相同的行为,没有报告错误.
这是代码(AVKit并AVFoundation导入):
var playerVC : AVPlayerViewController!
var playerItem : AVPlayerItem!
var player : AVPlayer!
var playerLayer: AVPlayerLayer!
override func viewDidAppear(animated: Bool) {
let bundle = NSBundle.mainBundle()
let path = bundle.pathForResource("testVideos", ofType: "m4v")
let url = NSURL.init(string: path!)
playerItem = AVPlayerItem.init(URL: url!)
player = AVPlayer.init(playerItem: playerItem)
playerVC = AVPlayerViewController.init();
playerVC.player = player;
self.presentViewController(playerVC, animated: true) { () -> Void in
self.playerVC.player?.play()
}
}
Run Code Online (Sandbox Code Playgroud)
构建到IpadMini 4时看到此警告: <CATransformLayer: 0x136ea1030> - changing property …
当按下按钮时,我正在制作一个简单的iPad应用程序来播放电影.电影播放,电影结束时我想关闭AVPlayerView,然后返回主屏幕.目前,当视频完成时,它将保留在最后一帧.我的ViewController.Swift此刻.
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
//MARK : Properties
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
//MARK: Actions
@IBAction func playButton(_ sender: AnyObject) {
let movieURL = Bundle.main.url(forResource: "ElephantSeals", withExtension: "mov")!
let player = AVPlayer(url: movieURL as URL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
// player.actionAtItemEnd = playerViewController.dismiss(animated: true)
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我认为actionAtItemEnd中可能存在某些内容,但我不确定如何实现它.谢谢.
当我从互联网上加载视频(10-40MB大)时,我无法提供流畅的播放体验.
我的AVPlayer要么加载整个视频然后播放,要么播放1s缓冲区然后停止播放.
我尝试了无穷无尽的库,缓冲区观察器方法和教程.似乎没有任何帮助.
.
.
.
self.makeLoaderVisible()
let playerItem = AVPlayerItem(url: url)
playerItem.addObserver(self, forKeyPath: "playbackBufferEmpty", options: .new, context: nil)
playerItem.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: .new, context: nil)
playerItem.addObserver(self, forKeyPath: "playbackBufferFull", options: .new, context: nil)
avPlayer?.replaceCurrentItem(with: playerItem)
avPlayer?.automaticallyWaitsToMinimizeStalling = false
avPlayer?.playImmediately(atRate: 0)
// avPlayer?.play()
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if object is AVPlayerItem {
switch keyPath! {
case "playbackBufferEmpty":
// Show loader
makeLoaderVisible()
case "playbackLikelyToKeepUp":
// Hide loader
hideLoader()
case "playbackBufferFull": …Run Code Online (Sandbox Code Playgroud) 我正在查看一个 Apple 项目,该项目演示了如何使用 TrueDepth 前置摄像头将人与背景分开。你可以在这里看到:
它工作得很好,但是有时如果我旋转我的脸,深度图会丢失一些数据点并剪掉我的脸和耳朵的部分。你可以在这里看到这个例子:https : //streamable.com/cstex
有没有人对如何改进这一点有任何想法?该AVPortraitEffectsMatte对象是完美的,如果你使用AVCapturePhotoOutput,但它似乎并没有对实时视频输入可作为处理时间过长,更新帧。
我注意到Apple的Clips应用程序具有完美的效果,不会夹住我的任何脸或耳朵,并且提供了良好的帧率:https : //streamable.com/5n96h 由于他们的应用程序不会丢失细节,因此不能仅仅依靠关于深度数据。或者,他们正在通过模型运行他们的深度数据以改进它(可能类似于他们用来生成 AVPortraiEffectsMatte 的专有模型)
关于如何获得类似结果或他们如何实现的任何想法?
我希望能够在iOS的捕获ARframe的深度数据存储在一个无损压缩的图像文件。
根据这次 WWDC演讲:
“在iOS 11中,我们支持两种深度图像。第一种是HEIF HEVC,这是一种新格式,也称为HEIC文件,并且那里对深度有一流的支持...第二种格式是JPEG。伙计,JPEG并不是要这样做,但无论如何,我们还是让它做到了,如果地图经过过滤,则为8位有损JPEG,或者如果其中没有数字,则使用16位无损JPEG编码保留所有非数字,我们将其存储为JPEG底部的第二个图像,因此,如果您熟悉它,它就像一个多图片对象。”
当我将原始深度缓冲区(16位)与从存储的图像像素明智检索的深度缓冲区进行比较时,将得到以下结果:
First Second
0.61865234 0.6196289
0.62109375 0.6196289
0.6269531 0.6274414
0.6298828 0.63134766
0.6328125 0.63134766
nan 0.003921509
nan 0.0
nan 0.0
nan 0.007843018
nan 0.003921509
即使当我在其中包含NAN的未过滤深度数据时,存储的数据也无法保存它们,并且看起来也不使用无损编码
这是我写的代码:
if let currentFrame = session.currentFrame, let depthData = currentFrame.capturedDepthData { // The session variable is an ARSession object
let outputURL: URL? = filePath(forKey: "test")
guard let cgImageDestination = CGImageDestinationCreateWithURL(outputURL! as CFURL, kUTTypeJPEG, 1, nil) else {
return
}
depthData.depthDataMap.normalize() // Normalizing depth data between 0.0 and …Run Code Online (Sandbox Code Playgroud) Apologies for the title, a little tricky to explain.
Imagine a user is listening to Spotify or something in the background while using my app, and they tap on a video to play it. The video defaults to muted, so Spotify continues. THEN the user hits unmute, so Spotify will pause, and the now unmuted video audio will start playing.
Now, turns out the video's audio wasn't so interesting and the user would prefer to listen to their music, so …
我发现自己处于一种需要模拟音频播放来欺骗操作系统控件并MPNowPlayingInfoCenter认为正在播放音频的情况。这是因为我正在构建一个播放多个音轨的播放器,并在创建一个连续的“音频”音轨之间暂停。我已经在应用程序本身内完成了所有设置,并且锁定屏幕控件工作正常,但我面临的唯一问题是当实际音频停止并且正在“播放”暂停时,锁定屏幕信息中心停止计时器,并且只有当另一个音轨开始播放时,它才会继续显示正确的时间和整体状态。
这是我从音频文件和暂停项目构建的音轨的示例:
let items: [AudioItem] = [
.audio("part-1.mp3"),
.pause(duration: 5), // value of type: TimeInterval
.audio("part-2.mp3"),
.pause(duration: 3),
... // the list goes on
]
Run Code Online (Sandbox Code Playgroud)
然后在我的自定义播放器中,一旦AVAudioPlayer完成当前项目的工作,我就会从数组中获取下一个项目,并.pause使用预定的播放器播放 aTimer或.audio使用AVAudioPlayer.
extension Player: AVAudioPlayerDelegate {
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
playNextItem()
}
}
Run Code Online (Sandbox Code Playgroud)
问题就在这里,一旦AVAudioPlayer停止,“正在播放”信息中心也会自动停止,尽管我一直在喂它新鲜的nowPlayingInfo。然后,当它碰到另一个.audio项目时,它会正确恢复并显示当前时间等。
我如何欺骗他们MPNowPlayingInfoCenter认为我“播放”我的.pause项目时正在播放音频?
我意识到我想要实现的目标可能仍然不清楚,但如果需要,我很乐意分享更多见解。谢谢!
A. 保留 1 秒长的空音轨,只要需要暂停即可循环播放。
B. 以编程方式创建具有适当长度的空音轨并播放它,而不是用于Timer跟踪暂停持续时间/进度并完全依赖 AVAudioPlayer 来处理和.audio …
我们发现使用所需的委托创建 HLS fMP4 视频AVAssetWriter时会泄漏内存。AVAssetWriterDelegate甚至在使用给定的段数据进行处理和存储之前。
当手动释放内存时(感觉这是错误的),内存泄漏似乎消失了。
即使在最小的情况下,记忆也会迅速增加。
import Cocoa
import AVFoundation
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
AVCaptureDevice.requestAccess(for: .video, completionHandler: {
_ in
})
}
private var fileWriter: AVAssetWriter!
private var videoInput: AVAssetWriterInput!
private var bufferAdaptor: AVAssetWriterInputPixelBufferAdaptor!
private var captureSession: AVCaptureSession!
internal let recordingQueue = DispatchQueue(label: "RecordingQueue", qos: .userInitiated)
internal let writerQueue = DispatchQueue(label: "WriterQueue", qos: .userInitiated)
@IBAction func startCapture(_ sender: NSButton) {
self.writerQueue.async {
let device = AVCaptureDevice.default(for: .video)!
try! device.lockForConfiguration()
device.activeFormat = …Run Code Online (Sandbox Code Playgroud) 我目前正在使用 AVPlayerViewController / AVPlayer 处理 HTTP 实时流媒体视频
我正在播放支持 .m3u8 文件的视频
它播放得很好,但我的问题是,我可以像我在生成 .m3u8 文件时设置 4 种分辨率一样拥有视频数据..,我现在可以在终点改变分辨率,问题是如何获得我在端点设置的所有值。我也在 android 中播放,并且使用 Track 我能够获取所有视频信息,但是在 ios 中我如何获取包含视频的所有详细信息,例如视频的高度、轨道、视频支持的分辨率等。
我已经搜索了很多,但无法成功.. 需要帮助提前致谢
#EXTM3U
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="stereo",LANGUAGE="en",NAME="English",DEFAULT=YES,AUTOSELECT=YES,URI="audio/stereo/en/128kbit.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="stereo",LANGUAGE="dubbing",NAME="Dubbing",DEFAULT=NO,AUTOSELECT=YES,URI="audio/stereo/none/128kbit.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="surround",LANGUAGE="en",NAME="English",DEFAULT=YES,AUTOSELECT=YES,URI="audio/surround/en/320kbit.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="surround",LANGUAGE="dubbing",NAME="Dubbing",DEFAULT=NO,AUTOSELECT=YES,URI="audio/stereo/none/128kbit.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Deutsch",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE="de",URI="subtitles_de.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO,LANGUAGE="en",URI="subtitles_en.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Espanol",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE="es",URI="subtitles_es.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Français",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE="fr",URI="subtitles_fr.m3u8"
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=258157,CODECS="avc1.4d400d,mp4a.40.2",AUDIO="stereo",RESOLUTION=422x180,SUBTITLES="subs"
video/250kbit.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=520929,CODECS="avc1.4d4015,mp4a.40.2",AUDIO="stereo",RESOLUTION=638x272,SUBTITLES="subs"
video/500kbit.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=831270,CODECS="avc1.4d4015,mp4a.40.2",AUDIO="stereo",RESOLUTION=638x272,SUBTITLES="subs"
video/800kbit.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1144430,CODECS="avc1.4d401f,mp4a.40.2",AUDIO="surround",RESOLUTION=958x408,SUBTITLES="subs"
video/1100kbit.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1558322,CODECS="avc1.4d401f,mp4a.40.2",AUDIO="surround",RESOLUTION=1277x554,SUBTITLES="subs"
video/1500kbit.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=4149264,CODECS="avc1.4d4028,mp4a.40.2",AUDIO="surround",RESOLUTION=1921x818,SUBTITLES="subs"
video/4000kbit.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=6214307,CODECS="avc1.4d4028,mp4a.40.2",AUDIO="surround",RESOLUTION=1921x818,SUBTITLES="subs"
video/6000kbit.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=10285391,CODECS="avc1.4d4033,mp4a.40.2",AUDIO="surround",RESOLUTION=4096x1744,SUBTITLES="subs"
video/10000kbit.m3u8
Run Code Online (Sandbox Code Playgroud) 当创建使用自定义视频播放器AVPlayer+ AVPlayerLayer+AVPictureInPictureController的iPhone运行iOS 14(7测试版)中的视频时,应用程序进入后的背景不会自动进入子母画面模式player.start()从UIButton的行动调用。
使用AVPlayerViewController似乎表明AVPictureInPictureControlleriOS 14 上存在问题的 问题不会重现,但我想知道是否还有其他人遇到过这个问题并知道任何解决方法。我也向 Apple 提交了这个问题rdar://8620271
示例代码。
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
private let player = AVPlayer(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)
private var pictureInPictureController: AVPictureInPictureController!
private var playerView: PlayerView!
private var playButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
playerView = PlayerView(frame: CGRect(x: 0, y: 44, width: view.bounds.width, height: 200))
playerView.backgroundColor = .black
playerView.playerLayer.player = player
view.addSubview(playerView)
playButton = UIButton(frame: CGRect(x: view.bounds.midX - …Run Code Online (Sandbox Code Playgroud)