Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

Swift落穂ひろい プトロコル準拠

Swiftで少しわかりにくかった所を整理しておきます。Swift3です。

二つのプロトコル準拠

複数のプロトコル準拠な変数宣言に&を使います。

let animal3:Animal & Helloable = seri

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
    }
}

ネットワーク

引き続き
developer.apple.com

の一部の要点

NSURLSessionを使う。

iOSとの互換がいるときはNSURLConnectionを使う。

dataTaskWithRequest:completionHandler:ないしdataTaskWithURL:completionHandler:を呼ぶ

NSURLRequestにはリクエストに必要な情報をつめる。

もう少し制御が必要な場合はNSURLSessionでデリゲートを実装する。

独自認証、リダイレクトに従う等をデリゲートで都度訊かれる。

ディスクにダウンロードするならNSURLSession

一時停止等もできる。

POST要求

  1. やはりリクエストを作る。
  2. コンテンツタイプの指定はsetValue:forHTTPHeaderField:
  3. メモリ上の短いデータはURLエンコード
  4. ディスクのデータはNSMutableURLRequest.setHTTPBodyStream でNSInputStreamとして。
  5. 大量のデータはCFStreamCreateBoundPairでストリームの組を作りNSMutableURLRequest.setHTTPBodyStreamで。
  6. 進捗状況はconnection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:

認証

  1. URLSession:task:didReceiveChallenge:completionHandler:の実装
    1. 証明書を渡す場合 NSURLSessionAuthChallengeUseCredentialで証明書を渡す。
    2. 認証せず処理を続行 NSURLSessionAuthChallengeUseCredentialでnilを渡す。
    3. キャンセルしたい NSURLSessionAuthChallengeCancelAuthenticationChallengeを渡す。
    4. OSにまかせる NSURLSessionAuthChallengePerformDefaultHandling
    5. 特定の型の認証拒否 NSURLSessionAuthChallengeRejectProtectionSpace

認証書オブジェクト作成

  1. ログインパスワード認証 credentialWithUser:password:persistence:
  2. 証明書ベース credentialWithIdentity:certificates:persistence:にSecIdentityRefを渡す。(SecIdentityRefはユーザのキーチェーンから、SecItemCopyMatchingで取得)

developer.apple.com

ネットワーク

iOSDevネットワーキングオーバービュー
developer.apple.com


詳細はリンク先をみるとして冒頭の要点をまとめてみる。

ネットワークは信頼性が低いから以下に注意。

  1. 必要なデータのみ通信
  2. タイムアウトじゃなくて取り消し手段を入れる
  3. というか遅い通信では取り消しできるようなUIにせよ
  4. DLは再開できるようにしてね
  5. 通信が切れてもオフライン状態でとにかく機能し続けるようにしてね
  6. モーダルでネットワークが切れたとか出さないでね。復旧したら自動的に再試行するように。
  7. 低レベルのAPIじゃなくて高レベルのAPIを使うように。
  8. セキュリティに気をつける(SSL, TLS活用)。 安全性はアプリ側責任 等

現実

  1. 負荷が高いとパケット紛失が起こるよ。通信はガタ落ちだよ。
  2. ネットワークリンクが飽和すると遅延が生じるよ。(ルータがトラフィックをバッファに保存しようとする)
  3. 公衆無線LANはHTTP要求に対しログインページを出そうとするよ。
  4. ファイアウォールが特定ポート以外への切断を遮断するよ。
  5. NAT(ネットワーク・アドレス変換)によってサーバからユーザへ向かう接続ができないことがあるよ。等

対策

  1. まずデータのアップロード・ダウンロードはユーザに時間と費用を課していることに気づけ。これを最小限にせよ。

なるべくまとめる。

  1. どんなときも一括ダウンロード。都度ダウンロードすると遅延にも脆弱になるし、操作性も悪くなる。
  2. ダウンロードの量を最小にしてローカルにキャッシュしてね。前回から更新があるかを問い合わせてダウンロードしてね。
  3. 大きな画像を小さく表示するならはじめから小さな画像を用意してね。
  4. キャッシュ容量は各自工夫して下さい。
  5. トレードオフがいつもあるよ。例えば商品画像が並ぶとき、この画像をどこまで一括ダウンロードすべきか。。

ネットワークの状況変化への備え

  1. いつでも圏外、機内モードWifiを切る等の自体に対処してね。
  2. ユーザが意図的に接続しようとしているかが重要だよ。そういうときはいつでも接続しようとするべきだよ。すぐに接続できないときはユーザがキャンセルしない限り再接続を試みようとして下さいね。SCNetworkReachabilityをうまくつかってね。接続状態はモダールでない手段で表示してね。
  3. バックグラウンドで接続しようとした場合もモーダルでダイアログとか表示しないでね。再試行するにしても時間を開けていくようにしてね。
  4. SCNetworkReachabilityは状態が変換したときに通知が飛ぶよ。でもこのAPIは接続を事前に判断するものではなくて、接続に失敗してその原因を調べる時に使ってね。

通信速度の判断

少量のデータをダウンロードしてそれに費やした時間から評価してね。この評価値は都度図り直して精度を高めてみてね。
動画配信とかで速度が再生に追いついていないときは低帯域幅用の処理に一時的に切り替えるとか。

遅延

  1. 遠隔ホストへの要求で、応答を待ってからやっているとどんどん遅れていくよ。同時に送ったほうが良い。
  2. NSURLConnectionのパイプライン処理 NSMutableURLRequest.setHTTPShouldUsePipeliningを使うと複数のHTTP要求を同時に出せるよ。

テスト

  1. XCodeのNetwork Link Conditionerツールを使って色々な状況で試験できるよ。
    1. 帯域幅を抑える。
    2. 応答時間を伸ばす。
    3. DNS応答に遅延を加える。
    4. パケット紛失

分単位の処理がでないように、でたらキャンセルできるように。

プロトコル指向+値型なコーディング

WWW2016におけるコーディングの指針

developer.apple.com

モデルは値型に
Viewのレイアウト調整はプロトコルジェネリクスを使ってUIViewから独立なクラスを作ると単体テストできる。
Controllerの状態はenum一つにまとめる。モデルの更新を通知してコントロールは差分を見てUIを更新すると更新が一箇所になる。

継承よりも合成、プロトコル(つまりインターフェイス)に対してコードを書くというのはGOFデザインパターンの設計方針と同じだ。

値型

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を設定する。

Profile

Profileは基本のpresetがあり、自分でも設定できる。
主な値は以下

100%LOSS

3G

  1. 下り 780kbps
  2. 下りパケットロス 0%
  3. 下り遅延 100ミリ秒

DSL

Edge

High Latency DNS

Very Bad NetWork

  1. 下りバンド幅 1000kbps
  2. 下りパケットロス 10%
  3. 下り遅延 500ミリ秒

Wifi

  1. 下りバンド幅 40000kbps
  2. 下りパケットロス 0%
  3. 下り遅延 1ミリ秒

railsやってみたインデックス

辞書でシンボルの利用

ハッシュの例 - Rodhos Soft

railsチュートリアル

多対多

多対多関係 - Rodhos Soft




改訂3版 基礎 Ruby on Rails 基礎シリーズ

改訂3版 基礎 Ruby on Rails 基礎シリーズ

AVFoundation関連のサンプルコード

Apple

基本AV Foundation for iOS and macOS - Apple Developerのコーナーへ見に行けばよい

sample code

かなりあるので用途別に整理したい。

  1. AVLoupe
  2. StitchedStreamPlayer
  3. AVFoundationPiPPlayer: Picture-in-Picture Playback with AVKit
  4. AVReaderWriter: Offline Audio / Video Processing
  5. Using AVAudioEngine for Playback, Mixing and Recording
  6. Real-time Video Processing Using AVPlayerItemVideoOutput
  7. AVFoundationSimplePlayer-iOS: Using AVFoundation to Play Media
  8. AVFoundationQueuePlayer-iOS: Using a Mixture of Local File Based Assets and HTTP Live Streaming Assets with AVFoundation
  9. AVCustomEdit
  10. VideoSnake
  11. AVMetadataRecordPlay: Timed Metadata Capture Recording and Playback
  12. AVPlayerDemo
  13. avTouch
  14. AVMovieExporter
  15. AVSimpleEditoriOS
  16. RosyWriter
  17. AVCam-iOS: Using AVFoundation to Capture Images and Movies
  18. AVCamManual: Extending AVCam to Use Manual Capture API
  19. AVLocationPlayer: Using AVFoundation Metadata Reading
  20. AVFoundation - Timecode Reader/Writer (avtimecodereadwrite)
  21. BracketStripes: Using the Bracketed Capture API
  22. Using AVFoundation APIs to record a movie with location metadata
  23. AVTimedAnnotationWriter: Using Custom Annotation Metadata for Movie Writing and Playback
  24. AVARLDelegateDemo
  25. AVCompositionDebugVieweriOS
  26. MTAudioProcessingTap Audio Processor
  27. SquareCam
  28. GLCameraRipple
  29. StopNGo for iOS
  30. AVCamBarcode: Using AVFoundation to Detect Barcodes and Faces
  31. HLS Catalog: Using AVFoundation to play and persist HTTP Live Streams
  32. AVAutoWait: Using AVFoundation to play HTTP assets with minimal stalls
  33. AVCaptureAudioDataOutput To AudioUnit iOS

document

前述のappleのコーナーをみにいくのが早い

  1. About AVFoundation
  2. Exploring AVFoundation
  3. Technical Note TN2310 AVFoundation - Timecode Support with AVAssetWriter and AVAssetReader
  4. Technical Q&A QA1668 Playing media while in the background using AV Foundation on iOS
  5. Technical Q&A QA1772 How to determine whether an AVPlayerItem can be played at rates greater than 1.0
  6. Technical Note TN2288 Example Playlist Files for use with HTTP Live Streaming プレイリストの内容

フレーム間予測

概要

  1. フレームの間の画像を予測し生成する。
  2. 動き補償とともに画像圧縮に用いる。

符号化の概要

符号化の可逆/不可逆

  1. 可逆符号化
  2. 不可逆符号化

符号化方式

  1. 予測符号化 フレーム内予測、フレーム間予測 ★ここ
  2. 変換符号化 離散フーリエ変換、ウェーブレット変換
  3. ベクトル量子化 
  4. エントロピー符号化 ハフマン符号化、算術符号化

符号化の参考サイト

画像符号化

Iフレーム、PフレームBフレーム

フレーム間予測を用いて圧縮した際、そのなかでも

  1. Iフレーム フレーム間予測を使わないフレーム(キーフレーム) ランダムアクセス等に使用
  2. Pフレーム  前方予測のみ使うフレーム
  3. Bフレーム 前方予測、後方予測、または両方を使うフレーム

フレームの間予測の参考サイト

Video compression - ビデオ圧縮 | Axis Communications

フレームレート

単位時間あたりの静止画像数(フレーム数)。1秒あたりをfpsと呼ぶ。

どの程度
  1. 8fps 一般のTVアニメ
  2. 15fps以下 カクカクする
  3. 24fps 映画
  4. 30fps 一般の動画、テレビ
  5. 60fps なめらかな映像が再現できる
補足
  1. 通信路容量の計算

HLSのメモ

基本的な事項の復習

HTTP Live Streamingの略
Appleの開発した動画ストリーミングのプロトコル
HTTPプロトコルを利用する

MPEG-2 TS

  1. 映像・音声データ
  2. MPEG-2 TSを10秒単位で細切れにし、エンコードする。エンコードビットレートに応じて幾つか作る。
  3. m3u8形式(プレイリスト、インデックスファイル)でこの細切れのファイルをどうつなげて再生するか指定する。

m3u8形式

m3u形式

パスないしURLの羅列、#はコメント

EXTM3U

拡張版

#EXTM3Uヘッダをファイル先頭につける。
#EXTINF 秒単位で長さ、タイトル等の拡張情報つける

例は以下を参照
M3U - Wikipedia

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


配信

httpなので通常のwebサーバでOK

クライアントの動き

1. まずインデックスファイルを取得する。
2. インデックスファイルで指定されたファイルをダウンロード
3. ある程度たまったらユーザに表示
4. #EXT-X-ENDLISTタグがある場合、終了、ない場合はは1に戻って新しいインデックファイルを取得

ツール

mediastreamsegmenter

MPEG-2 tsを分割する。インデックスファイルも作ってくれるコマンドラインツール。
man mediastreamsegmenter参照

mediafilesegmenter

エンコードされたメディアファイルを入力としてMPEG-2 tsにして分割。インデックスファイルも作ってくれる。

mediastreamvalidator

HLSと連動できるか検証するコマンド

variantplaylistcreator

mediafilesegmenter(-generate-variant-playlist付与)の出力から各種のビットレートのストリームを含むインデックスファイル作成

id3taggenerator

ID3メタデータタグ生成
アルバムのジャケット画像、アーティスト名、曲名、画像内の対象の名前と統計情報等も付与できる。
AVPlayerItem.timedMetaDataでアクセスできる。詳しくは「Timed
Metadata for HTTP Live Streaming」

mediastreamsegmenter(mediafilesegmenter)の-Fオプションでこのメタデータタグを追加できる。

セッションタイプ

VODとライブの二種類あり。

VOD

インデックスファイルが静的でその内容が全時間を表す。

ライブ

インデックスファイルは更新される。

暗号化

復号キーをインデクスファイルに付与しておく。



pip基本操作をメモ

pip -V pipのバージョン
pip list インストールしている#パッケージ一覧
pip -U パッケージ #インストールしているパッケージのアップデート
pip install パッケージ #パッケージのインストール
pip uninstall パッケージ #パッケージのアンインストール
pip search パッケージ #パッケージの検索

パッケージ検索は
PyPI - the Python Package Index : Python Package Index