GLKitミニマム
テンプレートを三角形が回転するだけのコードに削ってみた。
import GLKit import OpenGLES func BUFFER_OFFSET(i: Int) -> UnsafePointer<Void> { let p: UnsafePointer<Void> = nil return p.advancedBy(i) } class GameViewController: GLKViewController { var rotation: Float = 0.0 var vertexArray: GLuint = 0 var vertexBuffer: GLuint = 0 var context: EAGLContext? = nil var effect: GLKBaseEffect? = nil deinit { self.tearDownGL() if EAGLContext.currentContext() === self.context { EAGLContext.setCurrentContext(nil) } } override func viewDidLoad() { super.viewDidLoad() self.context = EAGLContext(API: .OpenGLES2) if !(self.context != nil) { print("Failed to create ES context") } let view = self.view as! GLKView view.context = self.context! view.drawableDepthFormat = .Format24 self.setupGL() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() if self.isViewLoaded() && (self.view.window != nil) { self.view = nil self.tearDownGL() if EAGLContext.currentContext() === self.context { EAGLContext.setCurrentContext(nil) } self.context = nil } } func setupGL() { EAGLContext.setCurrentContext(self.context) self.effect = GLKBaseEffect() self.effect!.light0.enabled = GLboolean(GL_TRUE) self.effect!.light0.diffuseColor = GLKVector4Make(1.0, 0.4, 0.4, 1.0) glEnable(GLenum(GL_DEPTH_TEST)) glGenVertexArraysOES(1, &vertexArray) glBindVertexArrayOES(vertexArray) glGenBuffers(1, &vertexBuffer)// 頂点バッファポインタ生成 glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer)// 有効化 // バッファに転送 glBufferData(GLenum(GL_ARRAY_BUFFER), GLsizeiptr(sizeof(GLfloat) * gVertexData.count), &gVertexData, GLenum(GL_STATIC_DRAW)) // 属性指定に頂点の位置を用いる事を指定 glEnableVertexAttribArray(GLuint(GLKVertexAttrib.Position.rawValue)) // glVertexAttribPointer(GLuint(GLKVertexAttrib.Position.rawValue), 3,// 1頂点あたりの要素の数 三次元なのでx,y,zの3 GLenum(GL_FLOAT), GLboolean(GL_FALSE), // ノーマライズされているか GLsizei(sizeof(GLfloat)*3), // 格納されているデータの間隔 BUFFER_OFFSET(0)) // データは並んでいる。 glBindVertexArrayOES(0) } func tearDownGL() { EAGLContext.setCurrentContext(self.context) glDeleteBuffers(1, &vertexBuffer) glDeleteVertexArraysOES(1, &vertexArray) self.effect = nil } // MARK: - GLKView and GLKViewController delegate methods func update() { let aspect = fabsf(Float(self.view.bounds.size.width / self.view.bounds.size.height)) let projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0), aspect, 0.1, 100.0) self.effect?.transform.projectionMatrix = projectionMatrix var baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0, 0.0, -4.0) baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, rotation, 0.0, 1.0, 0.0) // Compute the model view matrix for the object rendered with GLKit var modelViewMatrix = GLKMatrix4MakeTranslation(0.0, 0.0, -1.5) modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, rotation, 1.0, 1.0, 1.0) modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix) self.effect?.transform.modelviewMatrix = modelViewMatrix rotation += Float(self.timeSinceLastUpdate * 0.5) } override func glkView(view: GLKView, drawInRect rect: CGRect) { glClearColor(0.65, 0.65, 0.65, 1.0) glClear(GLbitfield(GL_COLOR_BUFFER_BIT) | GLbitfield(GL_DEPTH_BUFFER_BIT)) glBindVertexArrayOES(vertexArray) // Render the object with GLKit self.effect?.prepareToDraw() glDrawArrays(GLenum(GL_TRIANGLES) , 0, Int32(gVertexData.count/3)) } } var gVertexData: [GLfloat] = [ -0.5, -0.0, 0.0, 0.5,-0.5,0.0, -0.5,0.5,0.0 ]
Swift落穂ひろい プトロコル準拠
Swiftで少しわかりにくかった所を整理しておきます。Swift3です。
Switch文で特定の型に対して
protocol Animal { } protocol Helloable { func hello() } struct Dog : Animal,Helloable { let name:String let legs:Int let age:Int func hello() { print("bow!") } } struct Cat : Animal, Helloable { let name:String let legs:Int let age:Int func hello() { print("nyao!") } } struct Fish : Animal { let name:String let age:Int } let seri = Dog(name: "Seri", legs: 4, age:13) seri.hello() let tama = Cat(name: "Tama", legs: 4, age:5) tama.hello() let kin = Fish(name: "Kin", age:1) let animal:Animal = seri let animal2:Helloable = seri let animal3:Animal & Helloable = seri let animal4:Any&Helloable = seri let animals:[Animal] = [seri, tama, kin] animals.forEach { (p:Animal) in switch(p) { case let p as Animal & Helloable: p.hello() default: break } }
コンパイル時間計測
other Swift Flagsに-Xfrontend -debug-time-function-bodiesをつける。
ネットワーク
引き続き
developer.apple.com
の一部の要点
NSURLSessionを使う。
旧iOSとの互換がいるときはNSURLConnectionを使う。
dataTaskWithRequest:completionHandler:ないしdataTaskWithURL:completionHandler:を呼ぶ
NSURLRequestにはリクエストに必要な情報をつめる。
もう少し制御が必要な場合はNSURLSessionでデリゲートを実装する。
独自認証、リダイレクトに従う等をデリゲートで都度訊かれる。
ディスクにダウンロードするならNSURLSession
一時停止等もできる。
POST要求
- やはりリクエストを作る。
- コンテンツタイプの指定はsetValue:forHTTPHeaderField:
- メモリ上の短いデータはURLエンコード
- ディスクのデータはNSMutableURLRequest.setHTTPBodyStream でNSInputStreamとして。
- 大量のデータはCFStreamCreateBoundPairでストリームの組を作りNSMutableURLRequest.setHTTPBodyStreamで。
- 進捗状況はconnection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:
認証
- URLSession:task:didReceiveChallenge:completionHandler:の実装
- 証明書を渡す場合 NSURLSessionAuthChallengeUseCredentialで証明書を渡す。
- 認証せず処理を続行 NSURLSessionAuthChallengeUseCredentialでnilを渡す。
- キャンセルしたい NSURLSessionAuthChallengeCancelAuthenticationChallengeを渡す。
- OSにまかせる NSURLSessionAuthChallengePerformDefaultHandling
- 特定の型の認証拒否 NSURLSessionAuthChallengeRejectProtectionSpace
認証書オブジェクト作成
- ログインパスワード認証 credentialWithUser:password:persistence:
- 証明書ベース credentialWithIdentity:certificates:persistence:にSecIdentityRefを渡す。(SecIdentityRefはユーザのキーチェーンから、SecItemCopyMatchingで取得)
ネットワーク
iOSDevネットワーキングオーバービュー
developer.apple.com
詳細はリンク先をみるとして冒頭の要点をまとめてみる。
ネットワークは信頼性が低いから以下に注意。
現実
対策
- まずデータのアップロード・ダウンロードはユーザに時間と費用を課していることに気づけ。これを最小限にせよ。
なるべくまとめる。
- どんなときも一括ダウンロード。都度ダウンロードすると遅延にも脆弱になるし、操作性も悪くなる。
- ダウンロードの量を最小にしてローカルにキャッシュしてね。前回から更新があるかを問い合わせてダウンロードしてね。
- 大きな画像を小さく表示するならはじめから小さな画像を用意してね。
- キャッシュ容量は各自工夫して下さい。
- トレードオフがいつもあるよ。例えば商品画像が並ぶとき、この画像をどこまで一括ダウンロードすべきか。。
ネットワークの状況変化への備え
- いつでも圏外、機内モード、Wifiを切る等の自体に対処してね。
- ユーザが意図的に接続しようとしているかが重要だよ。そういうときはいつでも接続しようとするべきだよ。すぐに接続できないときはユーザがキャンセルしない限り再接続を試みようとして下さいね。SCNetworkReachabilityをうまくつかってね。接続状態はモダールでない手段で表示してね。
- バックグラウンドで接続しようとした場合もモーダルでダイアログとか表示しないでね。再試行するにしても時間を開けていくようにしてね。
- SCNetworkReachabilityは状態が変換したときに通知が飛ぶよ。でもこのAPIは接続を事前に判断するものではなくて、接続に失敗してその原因を調べる時に使ってね。
通信速度の判断
少量のデータをダウンロードしてそれに費やした時間から評価してね。この評価値は都度図り直して精度を高めてみてね。
動画配信とかで速度が再生に追いついていないときは低帯域幅用の処理に一時的に切り替えるとか。
遅延
- 遠隔ホストへの要求で、応答を待ってからやっているとどんどん遅れていくよ。同時に送ったほうが良い。
- NSURLConnectionのパイプライン処理 NSMutableURLRequest.setHTTPShouldUsePipeliningを使うと複数のHTTP要求を同時に出せるよ。
プロトコル指向の例
WWDC2015から
developer.apple.com
重要だが未消化なのであとで感想を追記したい。
値型
WWDC2015においてSwiftでは参照より値型を用いることを推奨している。
Building Better Apps with Value Types in Swift - WWDC 2015 - Videos - Apple Developer
参照型を混ぜる際にはgetにmutatingをつけてコピーして渡すようにする。
isUniquelyReferenceNonObjCを用いるとなお良い。
以下の説明が参考になる。
wpdev.hatenablog.com
iPhoneの実機でネットワーク環境を試す
図は「On-Demand Resources Guide: Optimization with Testing」を参照
設定
Settings/Developer/Network Link Conditioner/Status
enableをオンにし、
Profileを設定する。
railsやってみたインデックス
Modelからデータを取り出す
辞書でシンボルの利用
rake
scaffold
railsチュートリアル
RubyGem
Asset Pipe, Sass
モデルをつくる
AVFoundation関連のサンプルコード
Apple
基本AV Foundation for iOS and macOS - Apple Developerのコーナーへ見に行けばよい
sample code
かなりあるので用途別に整理したい。
- AVLoupe
- StitchedStreamPlayer
- AVFoundationPiPPlayer: Picture-in-Picture Playback with AVKit
- AVReaderWriter: Offline Audio / Video Processing
- Using AVAudioEngine for Playback, Mixing and Recording
- Real-time Video Processing Using AVPlayerItemVideoOutput
- AVFoundationSimplePlayer-iOS: Using AVFoundation to Play Media
- AVFoundationQueuePlayer-iOS: Using a Mixture of Local File Based Assets and HTTP Live Streaming Assets with AVFoundation
- AVCustomEdit
- VideoSnake
- AVMetadataRecordPlay: Timed Metadata Capture Recording and Playback
- AVPlayerDemo
- avTouch
- AVMovieExporter
- AVSimpleEditoriOS
- RosyWriter
- AVCam-iOS: Using AVFoundation to Capture Images and Movies
- AVCamManual: Extending AVCam to Use Manual Capture API
- AVLocationPlayer: Using AVFoundation Metadata Reading
- AVFoundation - Timecode Reader/Writer (avtimecodereadwrite)
- BracketStripes: Using the Bracketed Capture API
- Using AVFoundation APIs to record a movie with location metadata
- AVTimedAnnotationWriter: Using Custom Annotation Metadata for Movie Writing and Playback
- AVARLDelegateDemo
- AVCompositionDebugVieweriOS
- MTAudioProcessingTap Audio Processor
- SquareCam
- GLCameraRipple
- StopNGo for iOS
- AVCamBarcode: Using AVFoundation to Detect Barcodes and Faces
- HLS Catalog: Using AVFoundation to play and persist HTTP Live Streams
- AVAutoWait: Using AVFoundation to play HTTP assets with minimal stalls
- AVCaptureAudioDataOutput To AudioUnit iOS
document
前述のappleのコーナーをみにいくのが早い
- About AVFoundation
- Exploring AVFoundation
- Technical Note TN2310 AVFoundation - Timecode Support with AVAssetWriter and AVAssetReader
- Technical Q&A QA1668 Playing media while in the background using AV Foundation on iOS
- Technical Q&A QA1772 How to determine whether an AVPlayerItem can be played at rates greater than 1.0
- Technical Note TN2288 Example Playlist Files for use with HTTP Live Streaming プレイリストの内容
HLSのメモ
基本的な事項の復習
HTTP Live Streamingの略
Appleの開発した動画ストリーミングのプロトコル
HTTPプロトコルを利用する
MPEG-2 TS
m3u8形式
m3u形式
パスないしURLの羅列、#はコメント
m3u8形式はm3u形式の拡張
例
#EXT-X-VERSION:3 #EXTM3U #EXT-X-TARGETDURATION:10 #EXTINF:9.010, http://media.hoge.com/a.ts #EXTINF:9.001, http://media.hoge.com/b.ts #EXTINF:2.001, http://media.hoge.com/c.ts
これはVERSIONが3のプロトコルを満たす必要があることを意味する。EXTINFに浮動小数点数値でdurationを設定する。
各プロトコルで必須なものは以下に記載がある。
Understanding the EXT-X-VERSION tag
developer.apple.com
詳しくは HTTP Live Streaming draft-pantos-http-live-streaming-19
draft-pantos-http-live-streaming-19 - HTTP Live Streaming
iOS Devの資料
HTTP Live Streaming (HLS) - Apple Developer
https://developer.apple.com/jp/documentation/StreamingMediaGuide.pdf
配信
httpなので通常のwebサーバでOK
クライアントの動き
1. まずインデックスファイルを取得する。
2. インデックスファイルで指定されたファイルをダウンロード
3. ある程度たまったらユーザに表示
4. #EXT-X-ENDLISTタグがある場合、終了、ない場合はは1に戻って新しいインデックファイルを取得
ツール
mediastreamvalidator
HLSと連動できるか検証するコマンド
variantplaylistcreator
mediafilesegmenter(-generate-variant-playlist付与)の出力から各種のビットレートのストリームを含むインデックスファイル作成
セッションタイプ
VODとライブの二種類あり。
VOD
インデックスファイルが静的でその内容が全時間を表す。
ライブ
インデックスファイルは更新される。
暗号化
復号キーをインデクスファイルに付与しておく。
pip基本操作をメモ
pip -V pipのバージョン
pip list インストールしている#パッケージ一覧
pip -U パッケージ #インストールしているパッケージのアップデート
pip install パッケージ #パッケージのインストール
pip uninstall パッケージ #パッケージのアンインストール
pip search パッケージ #パッケージの検索
パッケージ検索は
PyPI - the Python Package Index : Python Package Index