Rubyと筋肉とギターとわたし

エンジニア二年目の雑魚です。プログラミング・ギター・筋トレのことをメインにブログを書いていきます。

kotlinで動画を再生する(VideoView)

kotlinでandroidアプリを絶賛開発中です。

androidをなるべくiOSっぽくするために日々奮闘しながら開発しているのですが、なかなかうまく行かない。

iOSでは動画を再生するときに自動でviewを作ってくれるのですが、androidではそういったことはしてくれないのでiOSっぽく動画を再生してみます。

ボタンクリック -> 動画再生 -> 終わったら元の画面へ

この流れで作成します。

環境

準備

activity2つ(empty activityでおk)・適当な動画が必要になります。

以下が手順。

まずはプロジェクト作成

名前は何でもおk。今回はMovieAppにしときます。

それ以外は変更せずnext連打で。

f:id:rdwbocungelt5:20180510102436p:plain

動画用viewを用意するためもうひとつactivityを作成します。

名前はMovieActivityで。

f:id:rdwbocungelt5:20180510102705p:plain

Activityの準備はこれでおk。



動画を入れるディレクトリを準備

動画のリソースはrawというディレクトリに格納します。音声ファイルもここ。

app/res上で右クリック、New -> Android Resource Directryを選択します。

f:id:rdwbocungelt5:20180510104906p:plain

Directory nameResource typerawに変更してOKを押下。

f:id:rdwbocungelt5:20180510104951p:plain

作成されたのが確認できました。

f:id:rdwbocungelt5:20180510105143p:plain

動画のリソースを入れる

今回はニコ二・コモンズから取ってきたこれを使います。

commons.nicovideo.jp

かっけぇ。

このファイルをctrl + cでコピーする。

なぜかubuntuandroid studioでは最初に選択したものが認識されないので、別のファイルを最初にして一緒に選択した状態でctrl + cでコピーする(意味わかるかな)。

そして、android studiorawディレクトリ上でctrl + vで貼り付け。

f:id:rdwbocungelt5:20180510110550p:plain

上みたいなウィンドウが出てくるので、ファイル名glass.mp4へ変えて「OK」。

f:id:rdwbocungelt5:20180510111216p:plain

ちゃんと入ってますね。

ファイル名に注意

リソースのファイル名は自由につけることが出来ますが、全角文字やハイフン、ドットをつけるとエラーになります。

元のファイル名が例えばglass-effect.mp4となっていた場合、貼付け時のウィンドウでglass_effect.mp4と変更するようにしましょう。

MainActivityとactivity_main.xml

MainActivityのレイアウトファイルにボタンを配置、MainActivityファイルでボタンを押した時のイベントを作成します。

activity_main.xmlファイルを編集

app/res/layoutにあります。

f:id:rdwbocungelt5:20180510111716p:plain

アプリ名が@string/app_nameとバグってますが気にしない。たぶんビルドしたら直るはずです。

まず最初に邪魔なhello worldの文字を消します。

選択してdeleteで。

f:id:rdwbocungelt5:20180510112109p:plain

準備おk。

パレットにあるButtonをドラッグアンドドロップで貼り付けます。

f:id:rdwbocungelt5:20180510112327p:plain

位置はとりあえず真ん中に持ってきましょ(そしたらレイアウト気にしなくていいので)。

Component treeのとこで注意マークが出てますが、今は気にしなくておkです。

次に右にあるAttributesのIDをstartButton、textをstartに変更します。

f:id:rdwbocungelt5:20180510112724p:plain

こんな感じ。

これでlayoutファイルの編集は完了。



MainActivityの編集

処理は簡単。

  • ボタン押下でMovieActivityに遷移する処理

これだけ。

ActivityでxmlのオブジェクトのIDを取得するときにわざわざfindViewByIdするのがだるい。

なので、import kotlinx.android.synthetic.main.activity_main.*をclassの前に記述します。

もろもろ書いたのが以下の画像。

f:id:rdwbocungelt5:20180510113243p:plain

xmlで設定したボタンのIDstartButtonを押した時の処理、setOnClickListenerの中に、移動する定石の処理を書いただけです。

これでMainActivityは完了。

MovieActiviryとactivity_movie.xml

xmlの背景を黒にし、VideoViewのオブジェクトを配置、Activityの方で動画の処理を書きます。

activity_movie.xmlの編集

まずは背景を真っ暗にします。

f:id:rdwbocungelt5:20180510115827p:plain

xmlのファイルを選択した状態で、左下らへんにあるTextを押すと、xmlの形式を直接変更できます。

7行目を追加すれば背景が黒になる。

でも、これは色の指定をxmlに直書きしているので、適切な場所で色を定義します。

app/res/colors.xmlで色を作成。

f:id:rdwbocungelt5:20180510120359p:plain

これをxmlから@color/blackで参照します。

f:id:rdwbocungelt5:20180510120527p:plain

Designの方を見てみると以下のように。

f:id:rdwbocungelt5:20180510152615p:plain

真っ暗になってますね。

次に、VideoViewを配置します。

f:id:rdwbocungelt5:20180510152844p:plain

Palette -> Widgets -> VideoViewをボタンのときと同じように配置。

配置すると画面全体に広がるので、画面中央に来るように縮小します。

f:id:rdwbocungelt5:20180510153132p:plain

ボタンの時と同じように、IDを変更。 videoVIew2からvideoViewへ(わかりやすければとりあえずおk)。

これで、xmlは完了です。

MovieActivityの編集

コードが以下。

f:id:rdwbocungelt5:20180510161151p:plain

import kotlinx.android.synthetic.main.activity_movie.*で該当のxmlのオブジェクトをIDで参照できるようにしています。

Handler(mainLooper).postDelayed({~~~}, 200)を設定しているのは、動画の読み込みに若干時間がかかるので設定(これがないと、動画の最初がキモいことなる)。

簡単な説明はコメントに書いてるので見てください。

もっとVideoViewについて知りたければこちら。

https://developer.android.com/reference/android/widget/VideoView



完成!!

ビルドをすると、Component treeに出ていた注意マークが消えます。

f:id:rdwbocungelt5:20180510163036g:plain

おわりに

gif動画の方では見せてなかったですが、動画をタップすると再生メニューが表示されるようになってます。

是非参考にしてみて下さーい。

なにかあればコメントに。



【備忘録】locateコマンドで検索結果が出なくなったとき

f:id:rdwbocungelt5:20180510095634g:plain

最近locateを使っても検索結果が出なくなったので放置してましたが、いい加減不便になってきたので改修しました。

原因

locateコマンドは予め用意されたDBを検索するので、更新してない状態では検索結果に現れないとのこと。

知らんかった。

環境

  • ubuntu 16.04.1 (elementary OS 0.4.1 Loki)

対処

$ updatedb
updatedb: `/var/lib/mlocate/mlocate.db' 用の一時ファイルを開けません

なんか出たのでスーパーユーザーでやります。

$ sudo updatedb

終わり

locateコマンドが参照するDBはこれで更新できました。
いつもどおりlocate <ファイル/ディレクトリ名>で検索できます。

これでやっとファイル検索ができる・・・。

画面遷移時に「Canvas: trying to draw too large bitmap」で落ちる

特にエラーも無く実装できたと思っていたんですが、意味のわからないエラーで落ちました。

結論を言えば、画像サイズがデカすぎて、入っているディレクトリにふさわしくなかったみたいです。

環境



ディレクトリの確認

android studioを最初開いた時は必要なディレクトリしか表示されないようになっています。

f:id:rdwbocungelt5:20180427133536p:plain

android」を押下して「Project」を選択。
すると以下のようなディレクトリ構造が出てきます。

f:id:rdwbocungelt5:20180427133708p:plain

僕の場合drawable-mdpiディレクトリに画像素材をガンガン入れていたんですが、それがダメだったようです。

なので、ひとつ上の階層のdrawable-xhdpiディレクトリにdrawable-mdpiにあった画像を全部ぶち込みます。

ドラッグ & ドロップでいけます。

ぶち込んだあとにまた「android」の方を表示するとこんな感じ。

f:id:rdwbocungelt5:20180427134150p:plain

後ろについてる括弧が入っているディレクトリを表してます。問題なさ気ですね。



これでもダメだったら。。。

もうひとつ上のディレクトdrawable-xxhdpiに入れてみてください。

解決するはずです。

何かあればコメントの方に。



Docker初心者が超絶簡単にDockerfileをまとめてみた その2

前回のブログの続き

smot93516.hatenablog.jp

前回使わなかった命令の中でよく使うものを紹介したいと思います。

実行環境

前回と一緒。

  • ubuntu16.04.1(elementary OS 0.4.1 Loki)
  • Docker version 17.12.0-ce

MAINTAINER命令

Dockerfileをチームで共有して開発する場合、誰がこのDockerfileを作ったのかを明示的にしておくようにします。

チームとしてはわかった方が嬉しいですよね。
多分Dockerfileとかコピペするだろうから意味ないと思うけど。

イメージ作成に直接関係があるかといえば、なんとも言えないです。
自分しか触らないのであれば書く必要は無いですね、きっと。

一応書き方。

MAINTAINER <名前>

# 例えばこんな感じ
MAINTAINER motty93 rdwbocungelt5@gmail.com

必要になったら書き方ググればいいと思います〜まあ無くても大丈夫かな。



WORKDIR命令

ディレクトリ移動の命令。
ディレクトリがなければ、自動的にディレクトリが作成されます。

FROM ubuntu

WORKDIR work

WORKDIR shop

RUN pwd

pwdの結果は/work/showです。

主にRUNCMDENTRYPOINTCOPYADD命令実行時の作業ディレクトリを指定するときに使います。

Rails環境を作った時にも使ったので、別の記事でそれはあげたいと思います。

VOLUME命令

(※1)マウントポイントを作成して外部マウント可能な(※2)ボリュームを作成する命令。

よく、データの永続化で使われます。
てかほとんどそれ。

FROM cenos:latest

RUN yum install -y httpd
RUN mkdir /var/log/httpd

CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

VOLUME /var/log/httpd

こんな感じにすると、apacheのログがVOLUMEで指定されたディレクトリへ溜まっていきます。
詳しくはdocker-composewordpress環境を作成するときに、データの永続化でやってみたいと思います。


※1 マウント:OSに読み書きできるように認識させる
※2 ボリューム:マウントされた領域のこと



ADD命令 & COPY命令

どちらかといえばCOPY命令を使った方がいいらしい。

第一引数に、ホストOS(自分のPC)のディレクトリ/ファイルを、第二引数にコンテナ内のディレクトリを指定します。

こんな感じ。

FROM centos

RUN mkdir app

# index.htmlはDockerfileと同じディレクトリにあるものと仮定します
ADD index.html /app

COPY index.html /app

要は、自分のPCのにあるファイルやらディレクトリやらをコンテナ内に持っていくって感じです。

コンテナ起動してから作成すればいいやん!って思った方、いると思います。

前回も書いたんですが、直接コンテナに入って行ったことは、コンテナを停止するとイメージを作成した状態まで戻ってしまいます(場合によります)。

だからイメージを作成する命令(Dockerfile)を書いてあげるんですよ(これで何回かハマりました、Dockerを理解していない証拠・・・)。

ENV命令

環境変数の設定です。

WORKDIR命令などのディレクトリを指定する命令と一緒に使われることがしばしばです。

FROM centos

RUN $DIR /dir

WORKDIR /usr/$DIR

COPY index.html /usr/$DIR

ここで環境変数を設定しておけば、コンテナを作成しても有効なままです。
設定されている値はdocker inspectで参照できます。

EXPOSE命令

特定のポートをコンテナが実行された時に読み取るようにdockerに教えてあげる命令です。

問題なのが、この命令があってもホストのブラウザからコンテナにアクセスできないんですよ。

なので、-pオプションで開くポートを指定する必要はあります。

FROM centos

RUN yum install -y httpd

EXPOSE 3000

CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

こんな感じで

$ docker run -d -p 3000 イメージ名

で起動できます。

いじょー

とりあえず主要なものだけピックアップして簡単に説明してみました。

初心者の説明なので、全く当てにならないかもしれないですが、参考にできるところだけ見てみてください。

今度はdocker-composeでいろんな環境を作ってみたいと思います。

お疲れ様でした!



Docker初心者が超絶簡単にDockerfileをまとめてみた その1

前回の記事で簡単なDockerfileを初めて作ってみました。

ですが、全くDockerfileの書き方について触れてなかった、というよりスルーしていたのでちょっとまとめてみたいと思います。
他にDockerfileの記事を書いている人はだいたいわかりにくい・・・

多分簡単です。慣れれば。

Dockerfileってなによ

簡単に言えば、「コンテナを作るときの説明書」および「手順書」のこと

Dockerfileのおかげで以下

  • dockerイメージを作成
  • コンテナ内で行うコマンド操作
  • 環境変数の設定
  • コンテナ内で動作させるデーモン実行

をビルド時に実行してイメージを作成したりします。

ね!簡単でしょ?

Dockerfileの命令一覧

命令 説明
FROM ベースイメージの指定
MAINETANER Dockerfileの作成者情報
RUN コマンド実行
VOLUME ボリュームのマウント
ADD ファイル/ディレクトリの追加
COPY ファイルのコピー
CMD デーモン実行
ENTRYPOINT デーモン実行
LABEL ラベルの設定
USER ユーザの指定
EXPOSE ポートのエクスポート
WORKDIR 作業ディレクトリの指定
ENV 環境変数の設定
ONBUILD ビルド完了後に実行される命令

上の表がDockerfileの命令です。 これを元にやっていきます。

今回はほんと簡単な命令しか書きません。
次回以降暇があれば記事にします。



実行環境

  • ubuntu16.04.1(elementary OS 0.4.1 Loki)
  • Docker version 17.12.0-ce

準備

わかりやすいようにディレクトリの準備をします。

$ cd ~ && mkdir docker-practice && cd !!$ && touch Dockerfile

homeディレクトリに移動してdocker-practiceディレクトリ作成&移動、Dockerfileを作成します。

FROM命令

DockerfileではコンテナはどのDockerイメージから生成するかという、「ベースイメージ」が必要なので、それをFROM命令で書いてあげます。

FROM イメージ名
or
FROM イメージ名:タグ名
or
FROM イメージ名@ダイジェスト

上記の形で書きます。
が、上2つだけ覚えておけばとりあえず大丈夫です。

たとえば、最新のubuntuイメージを取ってきたい場合は

FROM ubuntu:latest

でおk。超簡単。

試しにイメージを作ってみますか。
docker build -t <イメージ名> <Dockerfileのディレクトリ>で実行してみる(<イメージ名>:<タグ名>でタグをつけることができます)。

# 作成したDockerfileと同じディレクトリにいるはずなので"."でおk
$ docker build -t test .
Sending build context to Docker daemon  2.048kB
Step 1/1 : FROM ubuntu:latest
latest: Pulling from library/ubuntu
d3938036b19c: Pull complete 
a9b30c108bda: Pull complete 
67de21feec18: Pull complete 
817da545be2b: Pull complete 
d967c497ce23: Pull complete 
Digest: sha256:9ee3b83bcaa383e5e3b657f042f4034c92cdd50c03f73166c145c9ceaea9ba7c
Status: Downloaded newer image for ubuntu:latest
 ---> c9d990395902
Successfully built c9d990395902
Successfully tagged test:latest

まあまあ時間かかりました。

ちゃんとDockerfileを元にイメージが作成されているか確認してみる。

$ docker images
REPOSITORY              TAG                IMAGE ID               CREATED           SIZE
test                                latest              c9d990395902        2 days ago          113MB
ubuntu                           latest              c9d990395902        2 days ago          113MB

できてますね。

他のディレクトリにあるDockerfileを指定する時は、ディレクトリパスをdocker buildの最後に書いてあげてください。

今書いたDockerfileを元に別のイメージ名にしてdocker buildしてみると、前よりかなり早くbuildが完了するはず。
これは、ubuntu:latestベースイメージがローカル環境にダウンロードされているためです。

同じイメージを使用するときはかなり早くbuildできます。

RUN命令

コンテナ上で実行するコマンドの命令です。
CentOS系のyumUbuntu系のapt-getを元に検索かけていけばいいと思いますよ(多分)。

さっきのイメージを元にApacheを入れてみたいと思います。

FROM ubuntu:latest

# apt-getパッケージ管理のupdateとapache2のインストール
RUN apt-get update && apt-get install -y apache2 

aptコマンドは使えませんでした。
↑ いけたけど、WARNING: apt does not have a stable CLI interface. Use with caution in scripts.が出てあんま推奨されてないっぽい。

じゃあbuildしましょう。

# リビルドするときはタグ名を後ろにつけたらおk
$ docker build -t test:latest .
・
・
・
Step 1/2 : FROM ubuntu:latest
 ---> c9d990395902
Step 2/2 : RUN apt-get update && apt-get install -y apache2
 ---> Using cache
 ---> 5a2551cf2ad8
Successfully built 5a2551cf2ad8
Successfully tagged test:latest

Apacheインスコが終了しました。

ちょっと確認

本当に入っているかどうか、コンテナの中に入って確認してみます。

$ docker run -it c9d990395902 /bin/bash
# 

これでさっきのイメージIDを元にコンテナの中に入れます。

# apache2 -v
Server version: Apache/2.4.18 (Ubuntu)
Server built:   2017-09-18T15:09:02

ちゃんとApache入ってました\(^o^)/

ここでctrl + p + qを押せばコンテナを起動したまま出ることができますが、今回はその必要もないのでexitコマンドで出ます。
exitだとコンテナ起動と終了を一緒にやってくれます。

ちなみに

直接コンテナに入ってから、apt-getで何かパッケージをインスコした場合、exitで出てしまうとそのインスコはなかったことになります。

これは、imageがbuildした際の状態を保っているからです。

なので、「あれ〜この前インスコしたのになぁ〜」ってなったときはこの可能性が多いです。
要注意です。まじで。

CMD命令

デーモン実行。
イメージを元に生成したコンテナ内でコマンドを実行するために使うやつ。

ちなみにこいつはDockerfile内で一つしかかけない。複数書いた場合は、最後のだけが実行される。

さっきのDockerfileの最後に、Apacheサーバーを立てるコマンドを記載してみます。

FROM ubuntu:latest

# apt-getパッケージ管理のupdateとapache2のインストール
RUN apt-get update && apt-get install -y apache2

# デーモン起動
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]

ここでちょっと詰まったのですが、デーモン起動の際に/usr/sbin/apache2では起動しませんでした。
要注意です。

CentOSの場合は/usr/sbin/httpdです。

コンテナを起動

docker runでポート指定(-pオプション) & デタッチド(-dオプション)で起動します。

$ docker run -d -p 80:80 test

or

$ docker run -p 80:80 -d test

長い文字列が出ると思います。
なにか問題があればメッセージが出るはず。

本当に起動してるか確認しましょー。

docker psコマンドで。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
78fe3aafeada        test                "/usr/sbin/apachectl…"   4 seconds ago       Up 3 seconds        0.0.0.0:80->80/tcp   nervous_morse

動いてなければここで表示されないです。 今回はちゃんと表示されているので問題なしです。

特定のものだけ表示したい場合はフォーマットを指定すればおk。
例えばこんな感じ。

$ docker ps --format={{.Image}} {{.Command}} {{.Ports}}

こうすれば、イメージ名と実行したコマンド、ポートが表示されます。参考程度に。

画面の確認

ポートを80 -> 80に開放しているので単純にlocalhostでアクセスできます。

f:id:rdwbocungelt5:20180416101239p:plain

問題なさげ!

終わり

次回はファイルの追加やボリュームの指定、ポートのエクスポート等を簡単なDockerfileを元に作成したいと思います。

みんなDockerfileかけるようになろう(自問自答)。

じゃーの。

ubuntuで初めてのDockerfile

今まで人が作ったDockerfileを使ってdocker buildしていてほとんど触れていなかったのですが、それもDockerfileを作るのが難しいという勝手な苦手意識からでした。

ですがそうも言っていられないので、もっとdockerとお友達になるために超簡単なDockerfileを作成してみたいと思います。

環境

  • ubuntu16.04.1(elementary OS 0.4.1 Loki)
  • docker 17.12.0-ce

予想以上に簡単だった

最近Linuxに触れたからというのもあるとは思うのですが、結構簡単でした。

UNIXコマンドをDockerfileに書くことが多いので、Linuxの知識がある前提です。
Macでも同じようなコマンドが使えるのでLinuxを触っておいて損はないと思います。

てか、MacubuntuやらCentOSやらのコンテナ立ててシェルに入ってコマンドの練習すればいいんじゃないですかね。

winは知らん。

Dockerfileを作成する

それぞれ命令の意味はリファレンスが一番わかり易いと思います。

Dockerfile リファレンス — Docker-docs-ja 17.06.Beta ドキュメント

なんか適当なディレクトリを作ってそこにDockerfileを作成します。

$ mkdir ~/docker-pratice && cd !!$ && touch Dockerfile

ベースイメージをCentOS7にしてapacheでサーバーを立ててみます。

$ vim Dockerfile

FROM centos:centos7

RUN yum install -y httpd

CMD ["usr/sbin/httpd", "-D", "FOREGROUND"] 

多分これでおk。単純にCentOS上でapacheをインストールしてサーバー立てる命令を入れただけ。

ビルドするぞお

$ docker build -t docker-practice .
・
・
・
Complete!
Removing intermediate container 1f221c2502d5
 ---> 328e4875d499
Step 3/3 : CMD ["usr/sbin/httpd", "-D", "FOREGROUND"]
 ---> Running in 20abda19727c
Removing intermediate container 20abda19727c
 ---> 9f2a89281a6a
Successfully built 9f2a89281a6a
Successfully tagged docker-practice:lates

ビルド成功したのでイメージが作成されているか確認。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker-practice     latest              9f2a89281a6a        52 seconds ago      334MB

いけてますね\(^o^)/

作成したdockerイメージを起動する

先ほどのイメージでapacheコンテナを立てます。デタッチドでポートを指定して起動すれば行ける。

$ docker run -d -p 80:80 docker-practice

本当に起動しているのかわからんので一応確認。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
754fab174a33        docker-practice     "usr/sbin/httpd -D F…"   10 seconds ago      Up 9 seconds        0.0.0.0:80->80/tcp   gifted_boyd

おお動いてますね。

これでlocalhostにアクセスしてみる。

f:id:rdwbocungelt5:20180411115238p:plain

いけました\(^o^)/

最後に

立てたサーバーのコンテナは閉じるのを忘れないように。

$ docker stop 754fab174a33
#=> docker psで出てきたコンテナID

とりあえずここまで出来たらDockerfile作成できるって言っていいんじゃね?とか偉そうなこと思ってみたりする。

ubuntu(elementary OS)16.04.1へdocker-composeをインストール

smot93516.hatenablog.jp

前回のつづき的な感じです。

というか書き忘れてました\(^o^)/

リファレンスの言うとおり

以下を参照。

Docker Compose のインストール — Docker-docs-ja 17.06.Beta ドキュメント

最新のdocker-composeをcurlで取ってきます。

1.21.0-rc1がプレリリースされてますが安定しているかわかんないので一個前のやつにします。

github.com

$ curl -L https://github.com/docker/compose/releases/download/1.20.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
bash: /usr/local/bin/docker-compose: 許可がありません

許可がないみたいなので、sudoでやっちゃう。

$ curl -L https://github.com/docker/compose/releases/download/1.20.1/docker-compose-`uname -s`-`uname -m` > sudo /usr/local/bin/docker-compose
#=> まあまあ時間かかる

いけた!

docker-composeに対して実行権限を与えます。

$ chmod +x /usr/local/bin/docker-compose

ここでchmod: '/usr/local/bin/docker-compose' にアクセスできません: そのようなファイルやディレクトリはありませんと言われました。

見てみると、docker-composeファイルが存在しない。

てなわけで、root権限でcurlします。

$ sudo -i

# curl -L https://github.com/docker/compose/releases/download/1.20.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

# chmod +x /usr/local/bin/docker-compose

# exit  #=>root権限から抜ける

確認

$ docker-compose -v
docker-compose version 1.20.1, build 5d8c71b

無事docker-composeが入りました。

引き続きdocker教科書をやっていきまっす。