ohsnapy
ohsnapy

Reputation: 553

Play a video with AVPlayer in Swift Playground?

I am having trouble playing a video within a swift playground using AVPlayer.

Here's my code.

import UIKit
import AVFoundation

var f=CGRectMake(0, 0, 500, 500)
var url=NSURL(string: "http://s3.amazonaws.com/vids4project/sample.mp4")
var playerItem = AVPlayerItem(URL: url)

var v = UIView(frame:f)
var player=AVPlayer(playerItem: playerItem)
var playerLayer=AVPlayerLayer(player: player)

playerLayer.frame=f
v.layer.addSublayer(playerLayer)
player.play()

Any suggestions? The code as does nothing at all. My expectation is the 'v' variable should be showing the video. It seems to work outside the playground when I am connecting the avplayerlayer to a view from a storyboard.

Upvotes: 8

Views: 12050

Answers (5)

Lxrd-AJ
Lxrd-AJ

Reputation: 602

Another option to try is to use an AVPlayerView which can be set as the playground's live view.

import Foundation
import AppKit
import PlaygroundSupport
import AVFoundation
import AVKit


public func playVideo(at vidURL: URL) -> (AVPlayerView, AVPlayer) {
    print("Playing Video at \(vidURL)")
    let videoFrame = NSRect(x: 0, y: 0, width: 500, height: 500)
    let playerView = AVPlayerView(frame: videoFrame)
    
    let playerItem = AVPlayerItem(url: vidURL)
    let player = AVPlayer(playerItem: playerItem)
    
    playerView.player = player
    
    return (playerView, player)
}

guard let videoURL: URL = Bundle.main.url(forResource: videoFileName, withExtension: "mp4") else {
    fatalError("\(videoFileName) -> Video file not found")
}

let (playerView, videoPlayer) = playVideo(at: videoURL)

PlaygroundPage.current.liveView = playerView
PlaygroundPage.current.needsIndefiniteExecution = true

videoPlayer.pause() //videoPlayer.play()

Upvotes: 0

Hope
Hope

Reputation: 2326

For Swift 5.*

After reading several answers including the above ones I coded following. It works but with an issue player view placement a bit off. I mean when x and y values of its frame it should be at upper left corner but it does not sit there. The main issue was how to write url actually by the way.

import UIKit
import PlaygroundSupport
import AVFoundation
import CoreMedia


class MyViewController : UIViewController {

    var mPlayer : AVPlayer?
    var mItem   : AVPlayerItem?
    var playerLayer        : AVPlayerLayer?
    var playerView = UIView()  
  


    override func loadView() {
    
        let view = UIView()
        self.view = view
        view.frame = CGRect(x: 0, y: 0, width: 1000, height: 1000)
        view.backgroundColor = .darkGray
    
        let playerFrame = CGRect(x: 1, y: 10, width: 500, height: 500)
        playerView.frame =  playerFrame
        view.addSubview(playerView)
        playVideo()
   
    }

   func playVideo(){
        let url0 =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("IMG_0626.MOV")
    
    
        mItem                       = AVPlayerItem(url: url0)
        mPlayer                     = AVPlayer(playerItem: mItem!)
        playerLayer                 = AVPlayerLayer(player: mPlayer) 
    
        playerView.layer.addSublayer(playerLayer!)
        playerLayer?.frame          = playerView.bounds
        playerLayer?.videoGravity   = AVLayerVideoGravity.resizeAspect
        mPlayer?.play()
    }
}



// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
PlaygroundPage.current.needsIndefiniteExecution = true

Upvotes: 0

Justin Levi Winter
Justin Levi Winter

Reputation: 2737

The following should work if you drop it into a playground. Make sure to swap out the path: (Xcode 11 & Swift Playgrounds Mac & iOS)

import UIKit
import AVFoundation
import PlaygroundSupport

var playerFrame = CGRect(x: 0, y: 0, width: 500, height: 500)

guard let path = Bundle.main.path(forResource: "movie", ofType: "m4v") else {
    fatalError("no movie found")
}

let url = URL(fileURLWithPath: path)

var playerItem = AVPlayerItem(url: url)

var playerView = UIView(frame: playerFrame)
playerView.backgroundColor = .black
var player = AVPlayer(playerItem: playerItem)
var playerLayer = AVPlayerLayer(player: player)

playerLayer.frame = playerFrame
playerView.layer.addSublayer(playerLayer)
player.play()

PlaygroundPage.current.liveView = playerView

PlaygroundPage.current.needsIndefiniteExecution = true

Upvotes: 8

Bill Chan
Bill Chan

Reputation: 3455

Thanks of @Justin Levi Winter's answer and I had updated the code for Swift3, tested with Xcode 8 (This video plays in timeline, but not on the Quick Look):

import AVFoundation
import PlaygroundSupport


URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
let width = 568
let height = 320

let container = UIView(frame: CGRect(x: 0, y: 0, width: width, height: height))

PlaygroundPage.current.liveView = container

PlaygroundPage.current.needsIndefiniteExecution = true


func playVideo(_ url: URL){
    let f=CGRect(x: 0, y: 0, width: width, height: height)
    let playerItem = AVPlayerItem(url: url)

    let player=AVPlayer(playerItem: playerItem)
    let playerLayer=AVPlayerLayer(player: player)

    playerLayer.frame=f
    container.layer.addSublayer(playerLayer)
    PlaygroundPage.current.liveView = container

    player.play()
}

playVideo(URL(string:"http://s3.amazonaws.com/vids4project/sample.mp4")!)

Upvotes: 5

Gene De Lisa
Gene De Lisa

Reputation: 3838

Try adding this at the end to keep the playground running

import XCPlayground
XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)

Upvotes: 6

Related Questions