概要
動画メディアの時代なのでfacebookページから動画を取得したいときがあると思います。
今回は、
Page VideosのAPIで動画一覧を取得してidをモデルに保存、そのidを使ってVideoのAPIを叩いて動画詳細ページで動画を再生する方法を紹介します。
Facebook GraphAPIの基本的な使い方については 本家のドキュメントで勉強してください アクセストークンががないとリクエストできないです。あとSDKとかcocoapodsで入れてください。
グラフAPIエクスプローラでいろいろレスポンスをテストできるので試しながら実装してみましょう。
コードサンプル
以下は https://www.facebook.com/commonfitness/ というフィットネス動画メディアから動画一覧を取得したい時のコードのサンプルです。
Videoのモデルを作ってそのモデルをcollectionViewのセルに渡してサムネを表示することを想定しています。
動画一覧の取得
class Video {
var id = ""
var imageUrl = ""
var title = ""
}
class HomeViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
var videos: [Video] = []
override func viewDidLoad() {
super.viewDidLoad()
self.getVideos()
}
func getVideos(){
// facebook
let graphRequest:FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "/commonfitness/videos", parameters: nil, httpMethod: "GET")
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if error != nil {
print(error.debugDescription)
} else {
guard let videos = result as? [String: Any] else { return }
guard let datas = videos["data"] as? [[String: String]] else { return }
for data in datas {
let video = Video()
if let title = data["description"] {
video.title = title
}
if let id = data["id"] {
video.id = id
}
self.videos.append(video)
}
self.collectionView.reloadData()
}
})
}
}
extension HomeViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
...
}
idから小サムネイルの取得(楽だけど小さすぎ)
// こっちの方が多少取得が早いけれど画像が荒い
private func setThumbnailVeryEasy(_ videoId: String){
let imgUrl = "https://graph.facebook.com/\(videoId)/picture?fields=full_picture"
let url = URL(string: imgUrl)
imageView.sd_setImage(with: url)
}
idから大サムネイルの取得(またAPIたたかなければいけない)
// こっちは認証しないと取得できないけどサムネイルがめちゃ綺麗
private func setClearThumbNail(_ videoId: String){
let graphRequest: FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "/\(videoId)/thumbnails", parameters: nil, httpMethod: "GET")
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if error != nil {
print(error.debugDescription)
} else {
guard let datas = result as? [String: Any] else { return }
guard let data = datas["data"] as? [[String: Any]] else { return }
guard let firstData: [String: Any] = data.first else { return }
guard let imgUrl = firstData["uri"] as? String else { return }
let url = URL(string: imgUrl)
self.imageView.sd_setImage(with: url)
}
})
}
動画詳細ページ
idから動画のdata受け取ってAVPlayerで再生するまで。
動画のURLを取得した後は、
SwiftでVideo Player のやり方で動画を再生します。
class VideoViewController: UIViewController {
@IBOutlet weak var movieView: AVPlayerView!
var video = Video()
var videoPlayer : AVPlayer!
private var playerObserver: Any?
override func viewDidLoad() {
super.viewDidLoad()
title = video.title
requestFacebookVideoData()
}
deinit {
guard let observer = playerObserver else { return }
NotificationCenter.default.removeObserver(observer)
}
private func requestFacebookVideoData(){
// facebook
let params = ["fields": "source"]
let videoId = video.id
let graphRequest:FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "/\(videoId)", parameters: params, httpMethod: "GET")
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if error != nil {
print(error.debugDescription)
} else {
guard let data = result as? [String: String] else { return }
if let source = data["source"] {
self.setupVideoPlayer(source)
}
}
})
}
private func setupVideoPlayer(_ urlString: String){
let url = URL(string: urlString)
let avAsset = AVURLAsset(url: url!)
let playerItem = AVPlayerItem(asset: avAsset)
videoPlayer = AVPlayer(playerItem: playerItem)
// リピート再生したかったので書いたやつ
let resetPlayer = {
self.videoPlayer.seek(to: kCMTimeZero)
self.videoPlayer.play()
}
playerObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: videoPlayer.currentItem, queue: nil) { notification in
resetPlayer()
}
movieView.setVideoGravity(.resizeAspect)
movieView.setPlayer(videoPlayer)
self.videoPlayer.play()
}
}
以上。
注意点
アクセストークンがないとGraph APIでリクエストできないので、Facebookログインさせてユーザーのアクセストークンを取得するか、ページアクセストークンやアプリアクセストークンをサーバーから取得してリクエストする必要があります。
ページアクセストークンやアプリアクセストークンはアプリ内にハードコーディングするとセキュリティ的にマズイとのこと