2018年11月30日金曜日

介護における声かけに着目した介護職員に対する支援システムの提案

今回の輪読は「介護における声かけに着目した介護職員に対する支援システムの提案」を読んだ[1]。

論文概要

介護職員が正しく介護サービスを行えているかスマートフォンの音声認識を利用しテキストデータに変換しることで評価するシステムについての論文である。音声から必要な介護用語を抜き出せた割合は雑音無しの場合は67%、雑音有りでの場合は30%であった。評価方法には正規化レーベンシュタイン距離を用いたが検索結果の適合率を上げるために工夫する必要があるそうだ。

所感

普段介護現場がどのようにICT技術を使うのか知ることがなかったため、介護の評価を行うためにこのようなシステムを作り上げたのは興味深かった。テキストデータに変換した音声をMeCabを利用すると簡単に形態素解析できると知ったのでゼミでやってみたいと思った。雑音についてはマイクを用いたりして対策するそうなので、評価方法さえ見直せば介護現場で有用に活用できるシステムだと感じた。こうした音声認識技術を医療現場でどのようなことに利用できそうか考えたい。

参考文献

[1]佐藤央渉、澤本潤、杉野栄二:介護における声かけに着目した介護職員に対する支援システムの提案.「情報処理学会研究報告」, 2014.


【関連文献】 


  1. 在宅医療・介護従事者間のコミュニケーションを支援する音声つぶやき SNS
  2. 医療・看護・介護サービスにおけるコミュニケーション革新
  3. サービスの質を高める音声つぶやきによる気づきプラットフォームの研究

【音声認識エンジン】


  1. Julius
  2. Google Speech API の使い方 日本語音声をテキストに変換してみよう
  3. 音声操作にも。MonacaアプリとGoogle Cloud Speech APIで音声認識を実現しよう
  4. Monacaアプリで音声操作を可能にするdocomo発話理解APIの紹介
  5. モナカプレス

2018年11月21日水曜日

スマートフォンを利用した診療所のための服薬管理システム

今回の輪読は「スマートフォンを利用した診療所のための服薬管理システム」を読んだ[1]。

論文概要


入院していない患者の服薬忘れを防止するために、医師が患者の服薬状況をいつでも確認できることができるようなシステムを提案して、実際にスマートフォンで使用できるようなシステムを開発している。このシステムは患者にとっては自身の体調の改善などが期待でき、医師にとっては患者の服薬状況の確認ができ、全体としては効果的な処方につながることが期待できる。

所感


2018年ではスマートフォンのアプリケーションでは服薬管理をしているものが多々あるが、2013年ではスマートフォンで服薬管理などという医療関係のものは開発されていなかったと思うので2013年の時点ではこのアプリの開発はけっこうなことだったのではないかと思った。
 患者の個人情報はWebサーバに登録するので個人情報の管理は容易なことではないと思うのでしっかりとしたセキュリティが必要だと強く感じた。今後の地域医療には患者の身近に医療を構築することが重要になってくると思うのでスマートフォンで患者の健康を管理できるのはいいことだと感じた。

参考文献


[1]越野亮、中村竜規:スマートフォンを利用した診療所のための服薬管理システム. 知能と情報(日本知能情報ファジィ学会誌), 25(4), 787-795, 2013.

【Tips】

  1. e-pill CADEX 12 Alarm Watch
  2. ゼロから始める Google App Engine の使い方(2017年)
  3. Google App Engineで普通のWebサイトを格安にホスティングする
  4. あっ!くすり
  5. Pill Reminder - All in One

2018年11月19日月曜日

YES/NOチャート カメラで撮影する

今回のゼミではスマホのカメラで静止画像や動画を撮影できるようmonacaのYES/NOチャートを書き換えた。


<カメラ撮影(静止画像)>


 まずボタンを表示させたいページのHTML内の ons-pageタグにid属性を追加、
カメラを起動するためのボタン
<ons-button class="no-btn" onclick="takePicture()">
            カメラ
</ons-button>
リスト1.[カメラ]ボタン

 と撮影した画像を表示するタグ
<div id="viewport-C" class="viewport" style="display: none;">
            <img style="width:200px;" id="image-C"/>
</div>
リスト2.画像を表示するためのimgタグ

を追加する。

次にjavascriptにカメラボタンをクリックした際に呼び出されるプログラムを書く。
カメラアプリを起動し撮影に成功するとimgタグに画像を表示する。
function takePicture(){
  navigator.camera.getPicture(function(url){
    var viewport = document.getElementById('viewport-C');
    viewport.style.display = "";
    document.getElementById("image-C").src = url;
  },function(){
    alert('写真を撮影できませんでした');
  },{
    quality : 50,
    destinationType: Camera.DestinationType.FILE_URI,
    targetWidth: 500,
    targetHeight: 500
  });
}
リスト3.カメラアプリを起動し撮影するJavaScriptコード 

<カメラ撮影(動画像)>


動画の場合も写真の時とあまり変わらず、動画を呼び出すボタン
<ons-button class="no-btn" onclick="takeMovie()">
            動画撮影
</ons-button>
リスト4.[動画撮影]ボタンの作成

と撮影した動画を表示するタグ
<video id="movie-play" src="" width="320" height="240" controls></video>
リスト5.撮影した動画を再生するためのvideoタグ

を追加する。

次にjs/main.jsに[動画撮影]ボタンをクリックした際に呼び出されるコードを書けばよい。
function takeMovie(){
  navigator.device.capture.captureVideo(function(mediaFiles){
    mediaFiles.forEach(function( mediaFile ){
      var video = document.getElementById("movie-play");
      video.src = mediaFile.fullPath;
      video.play();
    });
  },function(error){
    alert('動画を撮影できませんでした');
  },{
    limit: 2
  });
}
リスト6.カメラアプリを起動して動画を撮影し再生するJavaScriptコード

カメラ機能はスマホならではの機能でとても良いものだと思う。
次回も今回学んだことを生かし新しいものを作っていきたい。

【Tips】

リスト6の動画撮影では次のCordovaプラグイン関数を使用している。
navigator.device.capture.captureVideo(
  撮影成功時に呼び出されるコールバック関数,
  撮影失敗時に呼び出されるコールバック関数,
  オプション
)
リスト7.動画撮影のCordovaプラグイン関数の書式

まず、オプションに設定している "{limit: 2}" は、2回動画を撮影することをカメラアプリに伝えている(正確には、何度でも撮影できるけれど、残すのは最後の2テイクのみという意味)。

次に、撮影成功時に呼び出されるコールバック関数は次のようになっている。
function(mediaFiles){
  mediaFiles.forEach(function( mediaFile ){
    var video = document.getElementById("movie-play");
    video.src = mediaFile.fullPath;
    video.play();
  });
}
リスト8.撮影成功時に呼び出されるコールバック関数

まず1行目の無名関数の引数 mediaFiles には撮影した2テイクの動画ファイルが入っている。2行目は、動画ファイルの各々に対して3~5行目の処理を行うという繰り返し制御である。
このように、JavaScriptでは配列要素の各々に対して処理を行う構文として forEach 構文がある。
配列名.forEach(function(配列要素){配列要素に対して行う処理});
リスト9.forEach構文

すなわち、リスト8では、撮影した動画の各々を "movie-play" という id がついた video タグのソースに設定して再生するという処理を行っている。

本来であれば2つの動画は異なるvideoタグに設定すべきであるが、このプログラムは同じタグに設定しているので、1つ目の動画が2つ目の動画に上書きされ、結果的に最後に撮影した動画のみが再生されるという結果になる。


2018年11月16日金曜日

覗き見攻撃耐性を考慮したスマートフォンにおけるリズム認証手法


今回は覗き見攻撃耐性を考慮したスマートフォンにおけるリズム認証手法-楽曲の主旋律を用いた際の認証制度評価-[1]を読んだ。

論文概要

第三者による覗き見攻撃を防ぐために安全性、利便性を兼ね揃えた認証方法についての論文である。この研究ではスマートフォンにおけるリズム認証の提案を行っている。「リズム認証」と画面を見ている状態で入力を行う「覗き見防止入力」で認証制度に差が生じるか検証を行っている。また、「覗き見防止入力」では音楽経験年数により認証精度に差が生じるかについても検証を行っている。その結果、認証精度には4.0%の差ができたと報告している。

所感

リズム認証手法というものがあるというのを全く知らなかったためとても興味深かった。
5年前にはスマートフォンのロックを外すのにはパスワードなどの画面を見なければ解除出来ないものばかりだったはずなので5年前にあれば認証精度も高いため実用できたと思う。だが、今は指紋認証や顔認証などがあるためそちらのほうが便利だと思った。
だが、リズムに合わせてタップして他人とリズムが同じになってしまうことがないのか疑問に思う。そのため時間があればゼミで実験してみたい。

参考文献

2018年11月12日月曜日

YES/NOチャート 効果音の修正と動画再生

今回のゼミでは前回作成した効果音のプログラムの修正と動画の再生をするようにスマホアプリを書き換えた。

<ページが開くと同時に音を出すプログラムの修正>

まず、先週入力したプログラムに間違いがあったため、index.htmlのons.ready(function() {});の{}内に書き込んだプログラムを削除した。
次に、音楽を再生したいページのHTMLファイル(resultA.htmlとする)にあるons-pageタグにid属性を追加した。(リスト1参照)
効果音は前回と同じサイトのものを使った。
https://maoudamashii.jokersounds.com/
<ons-page id="resultA">
リスト1

次に、jsフォルダの中にあるmain.jsの末尾に次のスクリプトを追加した。(リスト2参照)
document.addEventListener('postpush',function(event){
  if(event.enterPage.id=='resultA'){
    beep('https://maoudamashii.jokersounds.com/music/se/mp3/se_maou
damashii_jingle04.mp3');
  }
},false);
リスト2
これによりresultAのページに遷移した時に効果音が出るようになった。

<動画を再生するプログラム>

まず、Monacaのオブジェクトブラウザのwwwフォルダの下にvideoフォルダを作成した。
次に、動画をvideoファイル内にアップロードした。
次に、動画を再生したいページのHTMLファイル(resultB.htmlとする)のons-pageタグid="resultB"を付けて、</div>の上の行に次のスクリプトを追加した。(リスト3参照)
<videoid="video1"src="video/ZZZZZZ"width="320"height="240"controls></video>
リスト3 ZZZZZZの部分はアップロードした動画ファイルの名前


次にjsファイル内のmain.jsに次のスクリプトを追加した(リスト4参照:赤字部分)

document.addEventListener('postpush',function(event){
 if(event.enterPage.id=='resultA'){
  beep('https://maoudamashii.jokersounds.com/music/se/mp3/se_maoudamashii_jingle04.mp3');
 
} else if(event.enterPage.id == 'resultB'){
  var video = document.getElementById("video1");
  
video.play();
 
}
},false);
リスト4

これによりresultAのページに遷移した時に効果音だけでなく動画も再生されるようになった。

今回のゼミではページを遷移しただけで効果音を鳴らせたり、動画を再生することができるようになった。次回もMonacaにてより良い機能を追加していきたいと思う。

【TIPS】


動画を再生するプログラムにおいて、動画を再生したいページが音楽を再生したいページと同じ場合、HTMLファイル名をresultA.html、ons-pageタグのid属性をresultAとすると、リスト4は次のようになる。
document.addEventListener('postpush',function(event){
  if(event.enterPage.id == 'resultA'){
    beep('https://maoudamashii.jokersounds.com/music/se/mp3/se_maoudamashii_jingle04.mp3');
    var video = document.getElementById("video1");
    video.play();
  }
},false);
リスト5

リスト4との違いは、リスト4がif文を使ってevent.enterPage.idがpageAのときに音楽を鳴らし、event.enterPage.idがpageBのとき動画を再生しているのに対して、リスト5ではevent.enterPage.idがpageAのときに音楽と動画を同時に再生している点である。

イベントリスナ


スクリーンのタップ、画面の表示などのイベントを捉えて処理を実行するために聞き耳を立てる仕掛けをイベントリスナと言う。
イベントリスナは次のように書く。
document.addEventListener([イベントの種類], function(event){
    ・・・ここにイベント処理を書く・・・
  }
},false);
リスト6 イベントリスナ

リスト6において[イベントの種類]には、どのようなイベントが発生したかを表す文字列を書く。例えば、スクリーンをタップした場合は'click'、画面を表示(push)した直後は'postpush'、画面を閉じた(pop)直後は'postpop'などと書く。

無名関数


また、発生したイベントを受けて行う処理は下記の無名関数内で行う。
function(引数) { ・・・ここに関数の処理を書く・・・ }
リスト7 無名関数の書式

通常の関数は名前を持ち、beep関数のように必要な時に再利用される。
function 関数名(引数) { ・・・ここに関数の処理を書く・・・ }
リスト8 名前のある普通の関数の書式

これに対して、一度きりしか利用しない関数は名前を持つ必要がないのでリスト7のような書式になり、そのため無名関数と呼ばれる。
なお、リスト8は次のように書いてもよい。
関数名 = function(引数) { ・・・ここに関数の処理を書く・・・ }
リスト9 名前のある関数の別の書式 

前回やったbeep関数はこの書式になっている。

2018年11月9日金曜日

BLE センサとスマートフォンを利用した 認知症高齢者見守りサービスの研究

今回は「BLE センサとスマートフォンを利用した 認知症高齢者見守りサービスの研究1)を読んだ。

論文概論

少子高齢化が進み認知症高齢者の人口も増えている中でどうすれば認知症高齢者の方々が安心・安全に暮らすことが出来るのかという課題について考えたレポート。
研究ではbluetooth Low Energyを通信手段として使い実験を行っている。
方法は認知症の方にセンサを持たせ、センサと対応するアプリをインストールしてあるスマートフォンが半径10m以内ですれ違ったときセンサからアプリに位置情報が送られ、それをさらにクラウド経由で家族のもとへアプリを通じて情報が送られるという流れだ。
課題はどのようにしてアプリ利用者を収集するかだ。


所感

スマートフォンの普及により位置情報の特定は容易になったが、電力、サイズとの関係で直接親機との長時間の通信は現段階では厳しいが、第三者を通じて通信することで低電力かつ長時間通信することできることが分かった。
しかしアプリ利用者を増やすことが一番の課題であるためどうすれば世に広められたくさんの人に使ってもらえるのか考えていく必要がある。


参考文献
1. 永井 明彦、持田 昇一:BLE センサとスマートフォンを利用した 認知症高齢者見守りサービスの研究.2015年35巻1号p.55-58

2018年11月5日月曜日

YES/NOチャート 効果音

今回のゼミではYES/NOチャートの中に効果音を入れることを目標に前回作成したmonacaを改善した。

今回のキーワードは、”関数”
関数を使用し、YES/NOチャートで最終的にたどり着いた画面ごとに異なる効果音を出すようにブログに掲載されていた既存のプログラムを修正した。
関数に引数を与えることで、様々な異なる画面ごとで異なる効果音を出すことに成功した。

今回は beep=function() を利用して効果音を入れることにした。
効果音は次のサイトにあるのを使った。
https://maoudamashii.jokersounds.com/

<今回学習した内容>


字下げ


Javascriptでの記述で行末に "{" が書かれてある次の行は字下げ(たとえば2文字ずら)して記述すると見やすい(リスト1参照)。
var beep = function(url) {
    var my_media = new Media(url,
        function() {
            console.log("playAudio():Audio Success");
        },
        function(err) {
            console.log('playAudio():Audio Error:' + err);
    }).play();
};
リスト1
このプログラムで、1行目の末尾に "{" があるので、2行目は字下げしている。さらに4行目の行末にも "{" があるので5行目は字下げしている。

文字列定数と変数


 「"」(ダブルクォーテーション)や「'」(シングルクォーテーション)で囲んであるものは文字列定数、という意味。
何も囲んでないのは変数、という意味。
リスト1の例でいえば、2行目の「url」は変数で、4行目の"playAudio():Audio Success"や'playAudio():Audio Error:'が文字列定数。

「"」(ダブルクォーテーション)と「'」(シングルクォーテーション)の使い分け


文字列の中に文字列を書きたい時がある。そんな場合、下記の例のようにダブルクォーテーションで囲んだ文字列の中にシングルクォーテーションで囲んだ文字列を書く。
onclick="beep('https://maoudamashii.jokersounds.com/music/se/wav/se_maoudamashii_chime03.wav')"
今回のゼミの最初にjsのフォルダを作成するしようとした。その際に、既存のフォルダを移動してしまったらYES/NOチャートがきちんとした動作を起こさない可能性があると学んだ。このことから、最初からあるフォルダは絶対に動かしてはいけないということを学んだ。

次回はよりよいmonacaアプリを目指してページが表示されたら効果音が鳴りだしたり、動画を再生したりするアプリの作成を目標に頑張ります。

2018年11月2日金曜日

携帯情報端末を用いた外来患者システムの開発と実証

今回は「携帯情報端末を用いた外来患者システムの開発と実証1)を読んだ。

論文概要

フリーアクセスを原則とするわが国の医療においては,拠点病院において外来患者の待ち時間と医師の外来業務負担が増加している.医療の現場では外来患者の待ち時間対策が重要な課題であり,これに対し「携帯情報端末を用いた外来患者案内システム(POGS)」を開発した.
 POGSは患者自身の携帯情報端末に時間・空間の制約なく外来案内情報を提供する.病院外にあらかじめ設定されたエリア内で患者自身の携帯情報端末からのオンライン再来受付が可能であり,さらに,再来受付後の患者の携帯情報端末には,診察進捗通知・診察呼出・支払案内等がプッシュ配信され,患者は随時,受診票・診察進捗等を確認することも可能である.
 東京大学医学部附属病院の外来診療において協力患者10名(56.3±9.2歳)を対象にPOGSの実証試験を実施した.アンケート調査では,患者の待ち時間ストレスが高率(90%)に軽減されていることが確認された.診察呼出から診察室入室までの時間(呼出入室時間)についてPOGS利用群(n=20)では従来システム利用群(n=319)と比較して短縮される傾向(47±20秒vs 112±310秒, p=0.416, Wilcoxon rank sum test)があった.
 POGSは患者ストレス軽減効果のみならず,医師待ち時間および外来患者総待ち時間短縮効果を持つことが示唆される.

所感

スマートフォンや携帯電話を利用することにより、待ち時間に対してかなりの有効性があることが分かった。一方で、表示される文字が小さく読みづらかったり、スマートフォンそのものが苦手な患者もいるなどの課題もある。
従来の方式の良かった点を考えながらシステムを開発することも大切なのだと感じた。


参考文献

  1. 大前 浩司, 小林 春香, 内村 祐之, 脇 嘉代, 新 秀直, 田中 勝弥, 藤田 英雄, 大江 和彦 :携帯情報端末を用いた外来患者システムの開発と実証.医療情報学, 34(2), 55-64, 2014.

【コメント】

論文概要は、論文の要約をそのまま写し取るのではなく、自分がこの論文を読んで理解できた範囲で良いので、自分の言葉で書いてください。

Wilcoxon rank sum test(ウィルコクソンの符号順位検定)について調べてみました。これは、2群の代表値(中央値)に違いがあるかを検定するノンパラメトリック手法です(よく耳にするマン・ホイットニーのU検定と同じものだということです)。2群の代表値(平均値)の比較と言えばt-検定を思い浮かべますが、t-検定はデータに正規分布を仮定するパラメトリック検定手法です。
考え方としては、もし2群が同じ母集団からの異なるサンプルであれば、それらを一緒にして順番に並べ替えたら、いずれかの群が大きい方や小さい方に偏ることなく、ほどよく混ざり合うだろうと考え、それを表すような統計量を定義します。実際のデータをあてはめて統計量を計算し、それがどのくらい起こりやすいかを表す確率(p)をもとめ、それがあまりに小さいならば(有意水準よりも小さければ)、そんなことはありえないだろうと考えて帰無仮説(2群は同じ母集団からの異なるサンプルだという前提)を棄却するというものです。
この論文では、p=0.416となっていますから、有意水準5%で有意でないという結論になります。つまり、この程度の違いであればほぼ1/2の確率で起こるということです。

2018年11月1日木曜日

サウンドを出そう!

スマホでサウンドを出す方法について説明します。
まず、MonacaでYes/Noチャートのプロジェクトを開きます。左側のプロジェクトブラウザでwwwフォルダの下にjsフォルダを作成します。これはjavascriptを格納するためのフォルダとして使います。次にjsフォルダの中にmain.jsというファイルを新規作成します。その中に次のコードを書きます。
var beep = function() {
    var my_media = new Media("https://maoudamashii.jokersounds.com/music/se/wav/se_maoudamashii_chime03.wav",
        // success callback
        function() {
            console.log("playAudio():Audio Success");
        },
        // error callback
        function(err) {
            console.log("playAudio():Audio Error: "+err);
    }).play();
};
リスト 1
これは、音を鳴らす関数beepの定義です。
次に、index.htmlでmain.jsを取り込むように以下の1行を<head>~</head>の中に追加します。ほかにもscriptタグがいくつかあるのでその下に追加すればよいでしょう。
<script src="js/main.js"></script>
リスト 2
こうして定義したbeep音を出すにはbeep()関数を呼び出します。例えば下のコードのように、ボタンをクリックしたとき(onclick)にbeep()関数を実行します。
<ons-button class="no-btn" onclick="beep()">
    音楽
</ons-button>
リスト 3
なお、beep音の指定はリスト1の3行目で行っています。Mediaオブジェクトを生成するとき、出したい音のURLを引数に指定します。サウンドファイルであればどのような形式でもOKみたいです。
フリーの音源は下記サイトにあるのでいろいろと試してください。
https://maoudamashii.jokersounds.com/


ページが開くと同時に音を出す


ここまでだと、[音楽]とラベルの付いたボタンをクリックしないと音が出ません。ページが開くと同時に音が出るようにしてみましょう。
そのためには、ページが開いたというタイミングを捉まえる必要があります。これについては、下記のサイトに書いてあるons-nabigatorのイベントpostpushを利用します。
https://ja.onsen.io/v2/api/js/ons-navigator.html
詳細については、このサイトの「postpush」の記載を見てください。

以下に修正手順を示します。
まず、効果音を出したいページのHTMLファイルを次のように修正します。
ons-pageタグにid属性を付けます。その際、idの値はファイル名から.htmlを除いた部分とします。
例として、HTMLファイル名がresult_Cat.htmlの場合を以下に示します。
<ons-page id="result_Cat">
    <ons-toolbar>
        <div class="center">診断結果</div>
    </ons-toolbar>
    <div class="pagebody">
        <h1>猫タイプ</h1>
        <img src="images/cat.png">
        <p>猫タイプのあなたは、何ものにも縛られない自由人。気まぐれで自由奔放な性格に、周囲の人は振り回されているかも?</p>
        <ons-button class="retry-btn" onclick="document.getElementById('navi').resetToPage('question_A.html')">
            もう一度
        </ons-button>
    </div>
</ons-page>
リスト4
修正したのは1行目です。ons-pageタグの属性にid="result_Cat"を付け加えました。
次に、main.jsに次のコードを付け加えます。
document.addEventListener('postpush', function(event) {
  if(event.enterPage.id == 'result_Cat') {
    beep('https://maoudamashii.jokersounds.com/music/se/wav/se_maoudamashii_chime03.wav');
  }
}, false);
リスト5
これは、ページがプッシュ(表示)された後に発生するons-navigatorpostpushイベントを捉まえて、効果音を鳴らすための処理です。
どのページが表示されたかを判定するために、イベント関数に渡された引数evententerPageオブジェクトを調べます。
enterPageオブジェクトには、表示されたページの属性が入っています。どのページかを判断するにはid属性を見ます。
上記のリスト5では、id属性'result_Cat'の場合(つまりリスト4のページの場合)にbeep関数を使って効果音を鳴らしています。

【Tips】


Onsen UIはVer.1とVer.2では仕様がだいぶ変わっている。詳細は下記 Onsen UI 1.xからの移行を参照してください。
https://ja.onsen.io/v1/from-v1-to-v2.html
例えば、ons-navigatorタグにvar属性で名前を付けて、それを変数名としてjavascriptでons-navigator要素を操作するといったことはできなくなっています。id属性を付けて普通のDOM要素と同様にしてdocument.getElementByIdを使ってons-navigatorにアクセスします。また、イベントの捉え方なども違っているのでOnsen UI Ver.2のドキュメントを参照しながらプログラムする必要があります。


動画を再生する


次に動画を再生する方法について説明します。
まず、wwwフォルダの下に動画を保存するフォルダvideoを作成します。そして再生したい動画ファイルをその中にアップロードします。動画はスマホで撮影したものを使います。
動画の準備ができたら、まず、HTMLファイルを編集します。動画を再生するページ(例えばresult_Cat.html)の</div>タグの上に以下の<video>タグを追加します。
<video id="video1" src="video/XXXXXX" width="320" height="240" controls></video>
リスト6
ここで、XXXXXXの部分は自分が撮影してvideoフォルダにアップロードした動画ファイルの名前に置き換えてください。
次にjsフォルダにあるmain.jsを開いてリスト5のbeep関数呼び出しの下に動画を再生するプログラムを書きます。リスト5のプログラムを次のように書き換えてください。
document.addEventListener('postpush', function(event) {
  if(event.enterPage.id == 'result_Cat') {
    beep('https://maoudamashii.jokersounds.com/music/se/wav/se_maoudamashii_chime03.wav');
    var video = document.getElementById("video1");
    video.play();
  }
}, false);
リスト7
付け加えたのは4~5行目の2行だけです。これで完成しました。あとはスマホでアプリを動かして動画が再生できることを確認してください。


カメラで撮影する(静止画編)

cordova-plugin-camera v4.0.1 を使ってカメラアプリを起動する方法について解説します。ここでは、カメラアプリで静止画を撮影し、撮影した画像ファイルをスマホに保存するアプリを作成することにします。

まず、カメラを起動するためのボタンと撮影した画像を表示するページを作成します。ここでは、Yes/Noチャートのquestion_C.htmlを改造することにします。
question_C.htmlをリスト8に示します。
<ons-page id="pageC">
    <ons-toolbar>
        <div class="left"><ons-back-button>Back</ons-back-button></div>
        <div class="center">設問C</div>
    </ons-toolbar>

    <div class="pagebody">
        <h1 class="question">約束当日にドタキャンしたことが何回かある。</h1>
        <ons-button class="yes-btn"
            onclick="">
            はい
        </ons-button>
        <ons-button class="no-btn"
            onclick="">
            NO
        </ons-button>
        <ons-button class="no-btn" id="camera-btn-C"
            onclick="">
            カメラ
        </ons-button>
        <div id="viewport-C" class="viewport" style="display: none;">
            <img style="width:200px;" id="image-C" src="" />
        </div>
   </div>
</ons-page>
リスト8

追加したのは17~23行目です。17~20行目は「カメラ」というラベルの付いたボタンの定義で、21~23行目は撮影した画像を表示するためのimgタグです。下図はこうして作成したページCの画面です。

図1 ページCの画面

次にmain.jsの末尾にリスト9のコードを追加します。ここでは、ページが初期化されたときに発火するinitイベントを捉えて、そこに図1の[カメラ]ボタンがクリックされたときの処理を書きます。
document.addEventListener('init', function(event) {
  var page = event.target;
  if(page.id == 'pageC') {
    document.getElementById("camera-btn-C").addEventListener('click', function() {
      navigator.camera.getPicture(function(url){
        var viewport = document.getElementById('viewport-C');
        viewport.style.display = "";
        document.getElementById("image-C").src = url;
      }, function(){
        alert('撮影できませんでした!');
      }, {
        quality : 50,
        destinationType: Camera.DestinationType.FILE_URI,
        targetWidth: 500,
        targetHeight: 500
      });
    });
  }
});
リスト9 ページが初期化されたときの処理

1行目はinitイベントのイベントリスナの定義です。initイベントはページが初期化されるときに発火します。どのページが発火したかはeventオブジェクトのid属性で判定します。3行目のif文で"pageC"の場合に[カメラ]ボタンがクリックされたときのイベントリスナを定義します。

ここでは、[カメラ]ボタンが押されたら5行目でCordovaのカメラプラグイン(cordova.camera)を使ってカメラアプリを起動します。5行目のnavigator.camera.getPicture関数がそれです。この関数は第1引数に撮影が成功したときに実行するコールバック関数を、第2引数には失敗したときのコールバック関数を、そして第3引数にはオプションを書きます。
オプションには取得する画像の画質を指定するquality (0~100)やgetPicture()が返す形式を指定するdestinationType (Camera.DestinationType.DATA_URL: Base64でエンコードしたテキストデータを返す、Camera.DestinationType.FILE_URI:画像ファイルへのパスを返す)などを指定します。

撮影に成功したときは 6~8行目のコードが実行されます。画像表示領域を可視状態にし、imgタグのsrcプロパティに撮影した画像のURIを代入します。

図2.撮影した画像を画面表示


動画撮影 


次に動画を撮影して撮影するプログラムを書きます。動画を撮影するにはCordovaのメディアキャプチャプラグイン(cordova-plugin-media-capture)のnavigator.device.capture.captureVideo関数を使います。

ここでは、Yes/NoチャートのページEを使って動画撮影と再生を行います。リスト10はページEのHTMLです。
<ons-page id="pageE">
    <ons-toolbar>
        <div class="left"><ons-back-button>Back</ons-back-button></div>
        <div class="center">設問E</div>
    </ons-toolbar>

    <div class="pagebody">
        <h1 class="question">一人より大勢でいるほうが好きだ。</h1>
        <ons-button class="yes-btn"
            onclick="">
            YES
        </ons-button>
        <ons-button class="no-btn"
            onclick="">
            NO
        </ons-button>
        <ons-button class="no-btn" id="movie-btn-E"
            onclick="">
            動画撮影
        </ons-button>
        <video id="video-E" src="" width="320" height="240" controls></video>
    </div>
</ons-page>
リスト10

1行目のons-pageタグのid属性にpageEを設定します。
17行目~20行目は[動画撮影]ボタンの定義で、これをクリックするとカメラアプリが起動され、動画の撮影が行えます。
21行目は撮影した動画を再生させるためのvideoタグです。実際の画面は次のようになります。

図3 ページEの画面


次にmain.jsのinitイベントリスナにページEが初期化されたときの処理を書きます。
それをリスト11に示します。
  } else if(page.id == 'pageE') {
    document.getElementById("movie-btn-E").addEventListener('click', function() {
      navigator.device.capture.captureVideo(function(mediaFiles){
        mediaFiles.forEach(function( mediaFile ) {
          var video = document.getElementById("video-E");
          video.src = mediaFile.fullPath;
          video.play();
        });
      }, function(error){
        navigator.notification.alert('Error code: ' + error.code, null, 'Capture Error');
      }, {
        limit: 2
      });
    });
  }
リスト11

なお、リスト11では関係のない部分は削除しています。
2行目は[動画撮影]ボタンがクリックされたときに実行するイベント処理を登録しているところです。処理の中身はビデオ撮影です。これは navigator.device.capture.captureVideo()関数で行います。
この関数の第1引数には撮影成功時のコールバック関数が書かれています。その内容は、リスト10の21行目のvideoタグに撮影した動画を流す処理です。
実際の画面は次のようになります。

図4.動画再生


【TIPS】


Onsen UI (Monaca Version)を使った場合、ons-navigatorのpage属性にしたHTMLはons-templateタグを使ってindex.htmlと同じファイル内に書かないとDOMがRead Onlyになってしまうという奇妙な現象が現れた。
にもかかわらず、別ファイルにしてしまうと認識されない。よって、別ファイルにしつつ、index.html内にons-templateタグで存在のみ指定するという奇妙な書き方をしないとこの問題を回避できない。
この現象は、ons-navigatorのpage属性にしたHTML以外では生じないので、バグではないかと思うが、気持ちが悪いので、[設定]→[JS/CSSコンポーネントの追加と削除]でOnsen UI (Monaca Version)を削除した。