How to open data instead standart url in AVPlayer

做~自己de王妃 提交于 2019-12-25 02:25:40

问题


How i can open data video file instead standart url in AVPlayer?

let videoURL = URL(string: "https://example")

but instead URL i have only

var dataTs : Data = Data()

and i must put it in AVPlayerController

let player = AVPlayer(url: videoURL!)
playerViewController.player = player

回答1:


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.

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.

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.

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
}

Here's how you would use it:

var dataTs : Data = Data() // ...your data...

if let videoURL = setupNamedPipe(withData: dataTs)
{
    let player = AVPlayer(url: videoURL)
    playerViewController.player = player

    // ...do stuff...
}


来源:https://stackoverflow.com/questions/48229690/how-to-open-data-instead-standart-url-in-avplayer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!