如何在AVPlayer中打开数据而不是标准URL [英] How to open data instead standart url in AVPlayer
问题描述
我如何在AVPlayer中打开数据视频文件而不是标准URL?
How i can open data video file instead standart url in AVPlayer?
let videoURL = URL(string: "https://example")
但是我只有
var dataTs : Data = Data()
并且我必须将其放入AVPlayerController
and i must put it in AVPlayerController
let player = AVPlayer(url: videoURL!)
playerViewController.player = player
推荐答案
您无需将数据写入临时文件.您可以改用命名管道.除了不需要任何存储空间而且速度更快之外,这与写入临时文件非常相似.
You don't need to write the data to a temporary file. You can use a named pipe instead. It's very similar to writing to a temporary file, except that it doesn't require any storage space and it's faster.
如果您不熟悉命名管道,那么它们就没那么复杂了.它们看起来像文件,就像文件一样,但是文件中的数据不是来自存储介质,而是来自另一个进程或线程.它们是通过在Swift中看起来像这样的简单函数调用创建的:
If you're not familiar with named pipes, they aren't that complex. They look like and act like files, but rather than the data from the file coming from storage media, it's coming from another process or thread. They're created with a simple function call that looks like this in Swift:
mkfifo("foo", 0o666) // Note: 0o666 is Swift notation for octal values
在您的情况下,这是它的工作方式:您如上所述创建了命名管道.然后,您设置一个调度队列以打开文件并向其中写入数据.写操作将阻塞,直到出现其他情况并打开相同文件以从中读取文件为止.发生这种情况时,您的写入操作将解除阻止,并开始直接将数据发送到传入的读取请求.
Here's how it would work in your case: You create the named pipe as shown above. Then you setup a dispatch queue to open the file and write your data to it. The write operation will block until something else comes along and opens the same file to read from it. When that happens, your write operation will unblock and start sending data directly to the incoming read request.
一旦您的调度已建立并等待,就可以像平常一样继续进行操作,并传入指向您的命名管道AVPlayer
的URL
. AVPlayer
会认为它正在从文件中读取,但实际上是从dataTs
对象中读取数据.
Once your dispatch is setup and waiting, just continue along like normal and pass in a URL
that points to your named pipe to AVPlayer
. AVPlayer
will think it's reading from a file, but it's really reading the data from your dataTs
object.
您可以获得具有单个帮助程序功能的基本工作版本,该功能实际上将Data
对象转换为URL
以供一次性使用.这是一个Swift示例:
You can get a basic working version with a single helper function that essentially converts a Data
object into a URL
for one-time use. Here's a Swift sample:
func setupNamedPipe(withData data: Data) -> URL?
{
// Build a URL for a named pipe in the documents directory
let fifoBaseName = "avpipe"
let fifoUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last!.appendingPathComponent(fifoBaseName)
// Ensure there aren't any remnants of the fifo from a previous run
unlink(fifoUrl.path)
// Create the FIFO pipe
if mkfifo(fifoUrl.path, 0o666) != 0
{
print("Failed to create named pipe")
return nil
}
// Run the code to manage the pipe on a dispatch queue
DispatchQueue.global().async
{
print("Waiting for somebody to read...")
let fd = open(fifoUrl.path, O_WRONLY)
if fd != -1
{
print("Somebody is trying to read, writing data on the pipe")
data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
let num = write(fd, bytes, data.count)
if num != data.count
{
print("Write error")
}
}
print("Closing the write side of the pipe")
close(fd)
}
else
{
print("Failed to open named pipe for write")
}
print("Cleaning up the named pipe")
unlink(fifoUrl.path)
}
return fifoUrl
}
这是您将如何使用它:
var dataTs : Data = Data() // ...your data...
if let videoURL = setupNamedPipe(withData: dataTs)
{
let player = AVPlayer(url: videoURL)
playerViewController.player = player
// ...do stuff...
}
这篇关于如何在AVPlayer中打开数据而不是标准URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!