ionic3 localの動画をvideoタグで再生
はじめに
今回やりたかったことは以下
・フォトライブラリから選択した動画をvideoタグで再生
・カメラを起動して撮影した動画をvideoタグで再生
基本的な方針は以下に書いた画像の場合と同じ
http://kimagureneet.hatenablog.com/entry/2018/09/05/165323
1. ファイルへの絶対パスを取得。取得したパスに「file://」がついてなければ付ける
2. 1.で取得したURLを引数に、Ionic.WebView.convertFileSrcメソッド(cordova-plugin-ionic-webview)でローカルサーバーのURL(http://localhost:8080)に変換
3. 2.で取得したURLからBlob URLを作成
4. 3.で取得したBlob URLをvideoタグに設定
大きく違う点が3.で、localサーバーのURLからBlobURLを作成しているところ。Blob URLを使った理由は以下。
・iOSで再生できなかった
・Androidでは再生されるがvideo.currentTimeを設定しても期待した挙動にならなかった
それぞれ理由はわからないのだがブラウザの仕様なんじゃないかとちょっと気持ち悪いけど勝手に解釈。Androidのvideo.currentTimeが動かない点については同じコードでもローカルの動画の場合に期待通りに動かないということについてstack overflowでも触れられてる方がいた。
使用したプラグイン
・https://github.com/apache/cordova-plugin-camera
・https://github.com/apache/cordova-plugin-media-capture
実装
html
<button ion-button (click)="openPhoto()">フォトライブラリ</button> <video controls muted="true" webkit-playsinline playsinline preload="auto" style="width:100%;" [src]="videoUrl"></video> <button ion-button (click)="openCamera()">カメラを起動</button> <video controls muted="true" webkit-playsinline playsinline preload="auto" style="width:100%;" [src]="videoCameraUrl"></video>
javascript(typescript)
import { Component } from '@angular/core' import { Platform } from 'ionic-angular' import { Camera } from '@ionic-native/camera' import { PhotoLibrary } from '@ionic-native/photo-library' import { MediaCapture } from '@ionic-native/media-capture'; declare var Ionic :any declare var window; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { public imageUrl = "" public imageCameraUrl = "" constructor( public navCtrl: NavController, public platform: Platform, public camera: Camera, public mediaCapture: MediaCapture ) { } // フォトライブラリ openPhoto = () => { const options = { quality: 100, sourceType: this.camera.PictureSourceType.PHOTOLIBRARY, destinationType: this.camera.DestinationType.FILE_URI, mediaType: this.camera.MediaType.VIDEO } this.camera.getPicture(options).then((url) => { let videoPath = this.platform.is('android') ? 'file://' + url : url let videoUrl = Ionic.WebView.convertFileSrc(videoPath) this.createBlobUrl(videoUrl) .then(blobUrl => { this.presentVideoEditor(blobUrl, videoPath) }) .catch(error => { console.log(error) }) }) } // カメラ openCamera = () => { this.mediaCapture.captureVideo().then(data => { let url = Ionic.WebView.convertFileSrc(data[0]['fullPath']) if (this.platform.is('ios')) { url = 'file://' + url } this.createBlobUrl(url) .then(blobUrl => { this.videoCameraUrl = blobUrl }) .catch(error => { console.log(error) }) }, error => { console.log(error) }) } // Blob URL生成 createBlobUrl = (url) => { return new Promise((resolve, reject) => { var xhr = new XMLHttpRequest() xhr.open("GET", url) xhr.responseType = "blob" xhr.addEventListener('load', () => { // BlobデータからBlob URLを生成 let blob = xhr.response blob.name = 'file' blob.lastModifiedDate = new Date() let blobUrl = window.URL.createObjectURL(blob) resolve(blobUrl) }) xhr.onerror = (error) => { reject(error) } xhr.send(); }) } }
以上です