iOSでストリーミング再生中の動画キャプチャを撮りたいが方法がない
やりたいこと
サーバー上にあるm3u8ファイルをiPhoneアプリでストリーミング再生してる。
ボタンを押すと今映ってる映像の写真を撮ってローカルに保存したい。
一見、以下のような処理で簡単に取得できそうである。
let rect = view.bounds UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0) let context: CGContextRef = UIGraphicsGetCurrentContext() view.layer.renderInContext(context) let capturedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext()
が、真っ黒な画像が出力されるだけ。
色々調べたけど
色々試したけどできないっぽいよという回答。
A) UIGetScreenImage() という非公開メソッドで撮れるけど、リジェクトの可能性もあるよ
B) AVPlayerLayerで再生して、AVAssetImageGenerator の copyCGImageAtTime で撮れるよ
-> ただしこれは、サーバー上の動画ファイルには使えないみたい
stackoverflow.com
ここに載ってる方法でやってみたけど、imageRefが取得できない。
「できた!」って言ってる人は多分ローカルの動画ファイルでやってる気がする。
var url = NSURL(string: Constants.streamUrls[0]) if var asset = AVAsset.assetWithURL(url) as? AVAsset { var imageGenerator:AVAssetImageGenerator = AVAssetImageGenerator(asset: asset) var time = CMTimeMake(1, 1) var imageRef = imageGenerator.copyCGImageAtTime(time, actualTime: nil, error: nil) var thumbnail = UIImage(CGImage: imageRef) return thumbnail! }
以下のようなエラーを吐いてしまう。
Optional(Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x17046c140 {NSUnderlyingError=0x174243840 "The operation couldn’t be completed. (OSStatus error -12782.)", NSLocalizedFailureReason=An unknown error occurred (-12782), NSLocalizedDescription=The operation could not be completed})
stackoverflow.com こちらもうまくいかない。
AVAssetImageGeneratorを使っての取得も試みたが、ダメだった。
恐らくこちらも有効なのはローカルのビデオのみで、リモートの動画はだめくさい?
func captureFromPlayer(player: AVPlayer, maxSize: CGSize) -> UIImage? { var actualTime: CMTime = CMTimeMake(0, 0) var error: NSError? var generator: AVAssetImageGenerator = AVAssetImageGenerator(asset: player.currentItem.asset) generator.maximumSize = maxSize println("player.currentTime() :\(player.currentTime())") var cgIm: CGImageRef = generator.copyCGImageAtTime(player.currentTime(), actualTime: &actualTime, error: &error) var image = UIImage(CGImage: cgIm) if error != nil { println("erorr : \(error?.localizedDescription)") println("CMTimeGetSeconds : \(CMTimeGetSeconds(actualTime))") if let current = streamView.player?.currentTime() { CMTimeGetSeconds(current) } return nil } return image }
こっちもやってみたけど、そもそもtracksが空。
func setupReader() { let url = NSURL(string: urlString) let asset:AVURLAsset = AVURLAsset(URL: url, options: nil) asset.loadValuesAsynchronouslyForKeys(["tracks"], completionHandler: { dispatch_sync(dispatch_get_main_queue(), { () -> () in var videoTrack: AVAssetTrack? = nil var tracks = asset.tracksWithMediaType(AVMediaTypeVideo) if tracks.count == 1 { if let track = tracks[0] as? AVAssetTrack { var error: NSError? self.movieReader = AVAssetReader(asset: asset, error: &error) if error != nil { println("error: \(error)") } var key:String = kCVPixelBufferPixelFormatTypeKey as String var value:Int = kCVPixelFormatType_4444AYpCbCr16 as Int var videoSettings = [key: value] self.movieReader?.addOutput(AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoSettings)) self.movieReader?.startReading() } } }) }) }
iOS7から実装されたスナップショットを撮るメソッドを試す
こんなんあったんですね。
let capture: UIView = view.snapshotViewAfterScreenUpdates(true)
スクリーン自体のスナップショットを撮影するメソッドも、UIScreenに実装されている。
let capture = UIScreen.mainScreen().snapshotViewAfterScreenUpdates(true)
だがこれも、UIViewをUIImageに変換するこちらのお決まりのメソッドに投げると、
AVPlayerLayerの所だけが真っ黒になって返ってくる。
func viewToImage(capturedView:UIView) -> UIImage { UIGraphicsBeginImageContextWithOptions(capturedView.bounds.size, capturedView.opaque, 0.0) capturedView.layer.renderInContext(UIGraphicsGetCurrentContext()) var img = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return img }
ちなみに、キャプチャのUIView自体は、ビデオの動画もバッチリ表示されている。
UIImageにする段階で、ビデオ動画がすっぽり抜け落ちる。
なんでや!なんでなんや!
うーむ。。
こんなのもあった
これもだめだった
func snapByOpenGL() -> UIImage { if let time = streamView.playerItem?.currentTime() { if var pixelBuffer: CVPixelBufferRef = streamView.output?.copyPixelBufferForItemTime(time, itemTimeForDisplay: nil) { var ciImage = CIImage(CVPixelBuffer: pixelBuffer) var temporaryContext: CIContext = CIContext(options: nil) var rect = CGRectMake(0, 0, CGFloat(CVPixelBufferGetWidth(pixelBuffer)), CGFloat(CVPixelBufferGetHeight(pixelBuffer))) var videoImage: CGImageRef = temporaryContext.createCGImage(ciImage, fromRect: rect) var image = UIImage(CGImage: videoImage) return image! } } return UIImage() }
Instagramのハッシュタグつけたのに投稿が表示されない問題
今日(2015年8月22日)、Instagram の投稿にハッシュタグが反映されなくてすごく困った。
同じような現象が起こった時に誰かの役に立てばと思い、どんな事が起こったかまとめておく。
正確には以下の状態だった。
- コメント欄にハッシュタグを投稿する事は可能
- しかし、ハッシュタグの投稿一覧ページを見てみると「投稿0件」となってしまう。
- すでに投稿が数件あるようなハッシュタグをつけると、普通にそのハッシュタグの投稿一覧ページに反映される。
- ハッシュタグ検索ページ(以下url) を見ても、投稿0件になり、「このハッシュタグは通報されています」と表示される
#サンプルハッシュタグ • Instagram photos and videos
解決方法をググって以下を試してみた。
【解決方法1】プライベートモードを解除する
よくある話だが、自分のInstagramアカウントがプライベートモードになってて、
ハッシュタグ投稿一覧ページに反映されないパターン。
Instagramアプリの設定から、プライベートモードをOFFにすれば、即時反映されるようになる。
【解決方法2】「禁止ハッシュタグ」を投稿から削除する
インスタグラムには「バンされたハッシュタグ」が存在する。
エッチなものやスパム目的の投稿をはじくためや、
「photography」など抽象的過ぎるハッシュタグを禁止することで、写真を探しやすくするため、
という意図があるらしい。
ちなみにバンされたハッシュタグ一覧は以下
バンされたハッシュタグをつけた投稿は、他のハッシュタグ検索にも引っかからなくなる。
なので、バンされたハッシュタグをコメント欄から削除すれば、検索にひっかかるようになる。
【2】は今回初めて知ったが、他にハッシュタグを一切つけない状態でも投稿が正常に表示されない。。。
もしかして、この数日の間にスパム対策のためにInstagramに仕様変更があり、
全てのハッシュタグをデフォルトでバンし、
そのハッシュタグのついた投稿数が一定数になるまでバンされた状態になる、みたいな事になってるのか?
と思ってひたすら投稿したりいいねを押したりしていた。
【結論】Instagramの一時的なバグか
諦めかけた頃、突然ハッシュタグが反映されるようになった。
理由はわからないが、単なるインスタグラムのバグだったようだ。。
今日の朝にバグが発動し、16時頃修正された。
Twitterやgoogle の24時間以内検索をやってみると、以下のような投稿がひっかかった。
探してもこれくらいしか出てこなかったので、みんなあんまり困ってなかったのかな?
ともあれ、問題が解決して一件落着。よかったよかった。
新しいChromeで0.0.0.0:* にアクセスできない
いつからか、chromeのアドレスバーで0.0.0.0を入力してエンターを押すと、
0.0.0.0 という単語にアクセスしてしまうようになってしまいました。何で?
とりあえずhttp://localhost:* でアクセスするようにしましたが、
設定で変えることができるのでしょうか?
ご存知のかた、いらっしゃいましたら教えていただけると幸いです。
Node.jsで動画書出し
Video convert to WebM
http://www.sysord.fr/Sysord/ressource_whammy.jsf
Weppyを使ったwebm生成ライブラリ
https://github.com/antimatter15/whammy
Node.js & real-time video encoding
http://blog.romanliutikov.com/post/76000554454/node-js-real-time-video-encoding
フリーランス爆速スターターキットを作りたい
先日からフリーランスになった。
まだ事業開業届けも出していなければ、保険証も会社に返却して持ってない状態。
とりあえずお金の事は全部クラウド会計ソフトfreee にお任せすることにしたが、
今後のプランを組み立てるにあたって、稼ぐ額の目標を月いくらに設定すべきかもよくわかってない。
というのも、収入に対してのかかってくる税金がどれくらいなのか、まだ詳しくわかっていないのだ。
色々わからないことが多すぎて、開業する人はみんなこの道を通るのかと思ったら、
まとめて全部面倒見てくれるサービスがあったらいいのにと思った。
ので、サービス化するために自分が不便に思った点をまとめていく。
月どれくらい稼ぐと、どれくらい税金や健康保険で持っていかれるのか
税金シュミレーターとかネットにぼちぼち転がってはいるが、使いにくい。
以下を満たすようなシミュレーターがあるといい。
- 売上を入力すると様々な税金を差し引いたいわゆる「手取り額」がわかる
- どの項目が何のためのものなのかが一発でわかる
- 税率が変わるしきい値はどこかが一発でわかる
- 金額を入力するとその場で税金の数値もサクサク変わって、色々シミュレーションできる
健康保険
単純に計算したら年間で50万近く国民保険に支払う計算になった。マジか...
デザイナーなら文美国保というのに入れば安く済むみたい。
自分はデザインもやってるのでこれに入ろうと思う。
こういう情報もどこかにまとまっていればいいのに。
文芸美術国民健康保険組合 itereta.hatenablog.com
経費について
これは必要経費になるのか?みたいな話、検索すると色々出てくるけど、
体系的に見やすくまとめたサイトがあってもいいかなと思う。
今のところざっとこんな感じだ。
また欲しいものがあったらまとめていきたい。
WebSocket-Rails の記事まとめ
WebSocketを使ってリアルタイムなアプリが作りたいと思って、色々調べております。 github.com
Twitter Streaming APIからツイート受け取ってPUSH通知するアプリをHerokuに
ブラウザから位置情報を取得し別端末にPUSH通知を送るWEBアプリ
コラム - Ruby & Rails | 第14回 WebSocketでサーバプッシュ その3 ~Websocket-Rails~|CTC教育サービス 研修/トレーニング
代替 : EM-WebSocket
コラム - Ruby & Rails | 第13回 WebSocketでサーバプッシュ その2 〜EM-WebSocket〜|CTC教育サービス 研修/トレーニング
sinatraでやるなら
Ruby製WebSocketアプリを最速でHerokuにデプロイする5つのステップ