自分が使用しているFFmpegのコマンド例

ようやく今シーズンのイベントも落ち着いてきたので、まとめられていなかったものをまとめる時期に… 今回は結構毎回調べることが多かったFFmpegの中でも自分で使う機会の多かったをまとめて置こうと思います。

自分はWindowsとRaspberryPiで使うことが多いのでそのあたりの検証はしていませんが、Macは行えていません。 まあ、オプションなどの違いはないと思いますが、出来上がったもののCODECなどの問題はもしかしたらあるかもしれません。

インストール

省略してもいいのですが、FFmpegのインストールとなります。

Windowsの場合

以下のサイトにアクセスしてください。

FFmpeg

公式サイトに移動したら

f:id:ueponx:20181224120843p:plain

画面左の【download】をクリックします。

f:id:ueponx:20181224122528p:plain

クリックすると各プラットフォームのダウンロード画面になるので画面内nあるWindowsのアイコンをクリックします。

f:id:ueponx:20181224122752p:plain

マウスオーバーするとアイコンの色が変わります。

f:id:ueponx:20181224123323p:plain

クリックすると画面が少し下にスクロールして以下のようになります。 他のプラットホームでは種類があるのでリスト表示されますが、Windowsの場合には1つしかないようなのであっさりした表示になります。 【Windows Builds】をクリックします。

f:id:ueponx:20181224124049p:plain

すると、以下のようなダウンロードサイトに遷移します。

f:id:ueponx:20181224124538p:plain

画面内に(ビルド)Version、Architecture、Linkingの指定がありますので 今回は以下としました。 * Version 4.1 * Architecture Windows 64bit * Linking Static

選択が終わったら【Download Build】ボタンをクリックします。

f:id:ueponx:20181224124658p:plain

無事にダウンロードができました。

f:id:ueponx:20181224125313p:plain

ダウンロードをしたものはインストーラではなくバイナリファイルなので、binフォルダのプログラムが環境変数のPATHにあるフォルダに格納すればインストールは完了です。 自分は以下に展開して、環境変数PATHに``````を通しました。

C:\Program Files\ffmpeg

f:id:ueponx:20181224130352p:plain

このあたりは好みかと思います。

f:id:ueponx:20181224130858p:plain

こんな感じで実行できれば大丈夫です。

RaspberryPiの場合

aptコマンドを使います。以前はソースからのビルドを行う必要があったようですが、現在は大丈夫のようです。

$ sudo apt update
$ sudo apt install -y ffmpeg

インストール後のバージョンは以下のようになっていました。 version 3.2.10-1 結構古いです…

$ ffmpeg -version
ffmpeg version 3.2.10-1~deb9u1+rpt2 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 6.3.0 (Raspbian 6.3.0-18+rpi1+deb9u1) 20170516
configuration: --prefix=/usr --extra-version='1~deb9u1+rpt2' --toolchain=hardened --libdir=/usr/lib/arm-linux-gnueabihf --incdir=/usr/include/arm-linux-gnueabihf --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libebur128 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx-rpi --enable-mmal --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libiec61883 --arch=armhf --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
libavutil      55. 34.101 / 55. 34.101
libavcodec     57. 64.101 / 57. 64.101
libavformat    57. 56.101 / 57. 56.101
libavdevice    57.  1.100 / 57.  1.100
libavfilter     6. 65.100 /  6. 65.100
libavresample   3.  1.  0 /  3.  1.  0
libswscale      4.  2.100 /  4.  2.100
libswresample   2.  3.100 /  2.  3.100
libpostproc    54.  1.100 / 54.  1.100

新しいものを追っているわけではないので問題ないですが、以下の例で動かないときには注記することにします全部動いたようです。

説明の前提

例に使用するファイルの事前説明を書いておきます。

自分で使用するものは以下のようなものが多いです。音声のサンプリングレートは44.1kHzから48kHzにしていることも多いかなと思いますが 適宜入れ替えてもらえればいいかなと思います。

WAVファイル

  • 入力 → input.wav(44.1kHz Stereo 16bit)
  • 出力 → output.wav(44.1kHz Stereo 16bit)

MP3ファイル

  • 入力 → input.mp3(44.1kHz Stereo 192k)
  • 出力 → output.mp3(44.1kHz Stereo 192k)

使用例

WAVからMP3へ変換

$ ffmpeg -i input.wav -vn -ac 2 -ar 44100 -ab 192k -acodec libmp3lame -f mp3 output.mp3

ビットレート-abオプションで設定し、今回は192kを指定しています。

MP3からWAVへ変換

$ ffmpeg -i input.mp3 -vn -ac 2 -ar 44100 -acodec pcm_s16le -f wav output.wav

MP4形式の動画をAVI形式に変換する

$ ffmpeg -i input.mp4 output.avi

MP4形式の動画をビットレート340kbpsのMP4形式の動画に変換する

$ ffmpeg -i input.mp4 -vb 340k output.mp4

MP4形式の動画をフレームレート60fpsのMP4形式の動画に変換する

$ ffmpeg -i input.mp4 -r 60 output.mp4

画像の連番ファイルから動画をつくる

$ ffmpeg -i image%03d.png output.mp4

数字が連番になっているところをC言語のformat指定と同様な感じで%03dで指定して置換する。(わかりにくい?表現かも) ファイル名の桁数あわせで0埋めされていれば%0【桁数】dとし、数字が0埋めされていなければ%dで大丈夫です。

このまま実行するとWindowsのデフォルトプレイヤーやWindowsMediaPlayer再生できないというエラーが発生します。(VLCでの再生に関してはは問題ない)

f:id:ueponx:20181224142542p:plain

これで困るようであれば以下のようにCODECやpixelの色空間の指定を別途行います。

$ ffmpeg -i image%03d.png -vcodec libx264 -pix_fmt yuv420p output.mp4

こちらの指定であれば問題なく再生できました。

f:id:ueponx:20181224143930p:plain

画像の連番ファイルから60fpsの動画をつくる

$ ffmpeg -r 60 -i image%03d.png output.mp4

再生がうまくかなければ前段と同様にCODECやpixelの色空間の指定を行ってください。

$ ffmpeg -r 60 -i image%03d.png -vcodec libx264 -pix_fmt yuv420p output.mp4

動画から連番ファイルをつくる

$ ffmpeg -i input.mp4 image%03d.png

動画1秒あたりフレームレートの枚数分画像が生成するので、間引きを行うときは以下のように-rオプションを使って一秒当たりの静止画の枚数を指定することになります。

(例)動画から1秒あたり10枚の連番ファイルをつくる場合

ffmpeg -i input.mp4 -r 10 image%03d.png

動画をアスペクト比を保ったまま横幅640ピクセルにリサイズ、フレームレートは10fpsでアニメーションgifに変換

$ ffmpeg -i input.mp4 -vf scale=640:-1 -r 10 output.gif

アスペクト比を維持したままサイズを変える場合は、横幅か縦幅を-1にすればOKです。

動画を横幅1920ピクセル縦幅1080ピクセルにリサイズする

$ ffmpeg -i input.mp4 -s 1920x1080 output.mp4

動画からmp3形式で音声ファイルを生成する

$ ffmpeg -i input.mp4 output.mp3

動画を無音にする

$ ffmpeg -i input.mp4 -an output.mp4

動画の特定の時間範囲を取り出し

$ ffmpeg -ss [開始地点(秒)] -i [入力する動画パス] -t [切り出す秒数] [出力する動画パス]

(例)開始から10秒のところから、5秒間だけ切り出す場合

$ ffmpeg -ss 10 -i input.mp4 -t 5 output.mp4

動画をクロップしたい

$ ffmpeg -i 変換前ファイル -vf crop= 出力動画の幅 : 出力動画の高さ : 元動画の左上をゼロとして X 軸の距離 : 元動画の左上をゼロとして Y 軸の距離

(例)input.mp4を,左上を座標の原点(0,0)とし,そこから X=100,Y=60 を起点にして,W=160,H=120 のクロップしたoutput.mp4を出力する

図に表すと以下のようになります。(白い部分がクロップしたい部分になります)

f:id:ueponx:20181224133756j:plain

$ ffmpeg -i input.mp4 -vf crop=160:120:100:60 output.mp4

ffmpegでMP4ファイルを結合する

あるファイル(000.mp4)と別のファイル(001.mp4)を連続で再生する動画ファイル(output.mp4)を出力する。

まず、以下のように結合したいファイルを各行に記述したテキストファイルを作ります。 【list.txt】

file 000.mp4
file 001.mp4

各行の冒頭には必ずfileというキーワードが必要になります。 また、リストファイルに乗せるファイル名はフルパスを指定するほうがいいようなのですが、Windowsでは管理者権限でコマンドを実行してもPermissionのエラーが出るので相対パスのほうがいいようです。 対象になる動画と同じフォルダであれば、省略可能でした。

次に、このテキストファイルと同じディレクトリで以下のコマンドを実行します。

$ ffmpeg -f concat -i list.txt -c copy output.mp4

-c copyはオリジナルファイルのCODECを再エンコードしないオプションです。 異なるCODECの動画を結合したい場合は、-c copyを外すか別途CODECを指定する必要があります。

動画の再生スピードを変えて出力する

0.5倍速にする場合

$ ffmpeg -i input.mp4 -vf setpts=PTS/0.5 output.mp4

1.5倍速にする場合

$ ffmpeg -i input.mp4 -vf setpts=PTS/1.5 output.mp4

おわりに

あんまりないと思って甘く見ていたけど結構ありましたね。

2018年今年買ってよかったもの

今年購入してよかったものをちょっとだけ考えてみました。むしろ他の人が何を購入しているのかのほうが気になります。

今年買った中で役に立っているのはこちらです。

一位

いままでは家にも机があったのですが、スペースの関係で捨てることにしました。それからは作業するのは床座りという感じになっていました。 長い時間作業していると姿勢が悪くなり、膝が悪くなってしまいました。そこでパソコン用折りたたみテーブルを購入してみました。 ポイントにしたのは足の部分がY字になっている点(床が柔らかい状態でも安定します)と無段階調整の天板でした。いまのところ使い勝手もいいし軽いし折りたたみもできるので重宝しています。

難点があるとすれば天板についているパソコンの滑り止めがあるのですが高さがあるので使用したままキーボードはちょっと難しいかなとお思います。 もう一つはマウスレストが右側についていますが、外すことはできないです。あとレストがゴム製なので劣化すると使用感がどうなるかも気になります。

値段が3000円程度なのでまあいい買い物だったかなと思います。

二位

二位はRaspberry用の3.5インチタッチスクリーン機能付きのHDMIディスプレイです。 以下のエントリーをみて購入しました。

karaage.hatenadiary.jp

nomolk.hatenablog.com

見た瞬間にこれは買いだと思いました。 ケースがつくのもいいですが、GPIOのアクセスを妨げられないのが最高です。RaspberryPiのケースをつけると持ち運びは楽になるのですが GPIOへのアクセスがかなり制限を受けるので毎回困っていました。特にハッカソンなどでは持ち運びをすることを考えるとこの足枷が大きな障害になります。

これを使えばこれらの制限がなくなるのがいいですね。若干の大きさがあるので、一回り大きな箱はいりますが購入時の箱がそのまま使えますので捨てずにとっておくのがいいかなと思います。

価格も3300円ぐらいですが、モニターなしのケースでも1000円弱とかになってますので、モニタ付きのケースでこの値段ならまあそんなものかなと思います。

三位

Bluetoothイヤホンです。値段の割に音質もわるくないし、電池もなかなか持つというのが理由です。 イヤーピースの形がちょっと特殊なのでどうかなと思ったのですが、すぐに慣れました。フィット感と固定感もできて満足しています。

価格はセール中だったので2000円を切っていたかなと思います。セールが終わっていますが、同系統のものが2500円ぐらいで購入できそうです。

おわりに

今年は実用品ばっかりだったような気がします。もっと遊びがほしいです。

’e’の重要性

この記事はSeeed UG Advent Calendar 2018の22日目の記事です。 明らかにネタですが、いろいろとすみません。

Seeed社さんの商品を使ったブログのエントリーを書いていると、気をつけていないとついtypoしてしまい「e」が足りないことが結構あります。

そのまま誤記したエントリーをアップすると「Seeed警察*1」というパトロールが見回りを行っていて「e」が足りないという指摘を受けて、自分のTypoを実感してしまいます。

過去にはこんなエントリーを書いていましたが、これらの何件かはポリスの御用になっていました。

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

uepon.hatenadiary.com

そこで今回のエントリーではAdvent Calendar 2018の後半の箸休めとして、エントリー内にSeeedをSeedとするような誤記があるか調べるChrome拡張を作ってみることにしました。 これで安心してSeeed製品関連のエントリーを書くことができるでしょう。

あーえっとネタがちょっとなかったのですみません。

とりあえず

Chromeの拡張なのでバーにアイコンを表示してそれをクリックし、ページ内のコンテンツにseedがあるかないかを判定する機能を作ってみることにします。名前はSeeedポリス拡張機能としました。

Chrome拡張の開発に関しては以下のリンクのチュートリアルを参考にすれば比較的かんたんに実装することができます。

f:id:ueponx:20181209175437p:plain

Chrome拡張はHTMLとCSSJavascriptで作成し一つのフォルダ(ディレクトリ)の中に格納して管理します。

アイコンの作成

とはいっても、アイコン表示を行うのでアイコンも必要になります。Seeedさんということで以下のサイトで種と芽の形のアイコンを作ってみました。

icooon-mono.com

大きさはアイコンサイズではありますが48pixelあたりにしています。

f:id:ueponx:20181221164903p:plain

Manifestファイルを作成する

Chrome拡張にはManifestファイルが必要になります。Manifestでは、拡張機能に関する情報をjsonファイルで記述していきます。 内容としては拡張の名前やバックグラウンドで動作するJavascriptファイル(background.js)、拡張が動作可能な名前空間、アイコンクリック時に動作するJavascriptファイル(content.js)などの名前が記載されています。

今回のManifestファイルは以下のようにしました。

manifest.json

{
    "manifest_version": 2,
    "name": "Seeedポリス拡張機能",
    "description": "表示しているタブ内にSeedという単語が含まれているかチェックする拡張機能",
    "version": "1.0",
    "permissions": [
        "tabs",
        "notifications"
    ],
    "background": {
        "scripts": [
            "background.js"
        ]
    },
    "content_scripts": [
        {
            "matches": [
                "<all_urls>"
            ],
            "js": [
                "content.js"
            ]
        }
    ],
    "icons": {
        "48": "Extension48.png"
    },
    "browser_action": {
        "default_icon": "Extension48.png",
        "default_title": "Seeedポリス拡張機能"
    }
}

Content Scriptの記述

Chromeの拡張バーに表示されたアイコンをクリックすると動作する処理になります。

Manifestファイルのcontent_scriptsで指定したJavascriptファイル(今回はcontent.js)がこれに当たります。

このファイルは実行環境の制限が特殊でisolated worldと呼ばれています。制限事項は以下のようになっているようです。

という制限があります。今回はブラウザで開いているページのコンテンツを対象とするのでDOMを使用して、コンテンツのbodyタグを取得しました。ただこれだけでは、完了できなかったのでChromeの拡張のランタイムにbodyタグの内容をメッセージとして送信し、送信した内容をバックグラウンド側の処理で対応してもらうことにしました。

content.js

chrome.runtime.sendMessage({
    value: document.getElementsByTagName('body')[0].outerText
});

短いですがこんな感じになりました。

Background Pageの記述

先程のContent Scriptで機能制限がかかるのでその際に対応する手段としてBackground Pageがあります。Chrome拡張はバックグラウンドで動くページを持っていて、そちら側で処理を行うことができます。

今回はManifestファイルの"background"に指定したbackground.jsを編集します。 先程のcontent.jsで表示しているページのBodyタグの内容をMessageとして送信したので、 こちらのファイルでそのメッセージを受信し、seedという文字列が入っていたらChromeの通知(トースト?)を表示することにします。

  • 通知を受け取る場合には → chrome.runtime.onMessage.addListener()
  • アイコンのクリックを検知するには → chrome.browserAction.onClicked.addListener()

というイベントのリスナにfunctionを記述します。

background.js

let textContents = '';

chrome.runtime.onMessage.addListener(
    function (request, sender, sendResponse) {
        textContents = request.value;
        if (textContents.toLowerCase().search(/seed/) !== -1) {
            textContents = "含む";
        } else {
            textContents = "含まない";
        }
    }
);

chrome.browserAction.onClicked.addListener(
    function (request, sender, sendResponse) {
        let options = {
            type: "basic",
            title: "Seeed ポリス出動します!",
            message: "",
            iconUrl: "Extension48.png"
        };
        console.log("debug", options);
        if (textContents.indexOf("含む") !== -1) {
            options.message = "ページ内に”Seed”が含まれています、\n念の為確認してください!";
        } else {
            options.message = "ページ内にSeedは含まれていません、\nご安心ください!";
        }
        chrome.notifications.create(options);
        console.log("debug", options);
    }
);

chrome.runtime.onMessage.addListener()の処理では受け取ったメッセージのテキストの中にseedが 含まれるかチェックしています。

chrome.browserAction.onClicked.addListener()の処理ではseedが含まれていたら通知(chrome.notifications.create())を発生する処理を行っています。

ディレクトリの中がこんなふうになっていればいいかなと思います。

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2018/12/09     14:32           1076 background.js
-a----       2018/12/09     13:16             96 content.js
-a----       2018/12/09     12:08           2226 Extension48.png
-a----       2018/12/09     14:20            770 manifest.json

ローカル環境で配置

では、Chromeに拡張を配置します。Chromeで以下のURLを開きます

chrome://extensions/

すると、このような画面になります。

f:id:ueponx:20181209173718j:plain

(メニューから【その他ツール】→【拡張機能】でも同じ画面になります。)

画面の左上方にある【デベロッパーモード】を有効にするとメニューが追加されます。

デベロッパーモードの無効】 f:id:ueponx:20181222091503p:plain

デベロッパーモードの有効】 f:id:ueponx:20181222091731p:plain

この中から【パッケージ化されていない拡張機能を読み込む】をクリックします。 クリックするとディレクトリの選択のダイアログが開きます。

f:id:ueponx:20181209173805j:plain

ここで、先程保存しておいた拡張機能のフォルダを選択します。 うまく読み込むことができれば行けばこのように作成した拡張機能が表示されます。

f:id:ueponx:20181209174349p:plain

拡張機能のバーにアイコンの表示されているのも確認できます。

f:id:ueponx:20181209173858j:plain

アイコンをクリックすれば、Chromeの通知機能でseedが含まれているか否かを教えてくれます。

f:id:ueponx:20181222101234p:plain

f:id:ueponx:20181222102240p:plain

終わりに

いろいろネタがなくてすみません… eが大切なGReeeeNにも使えそうです。

*1:なぜか組織されているらしい

初めてファシリテーターらしきものを体験してみた話

このエントリーはMashupAwardsヒーローズ・リーグ Advent Calendar 2018の14日目のエントリーとなります

はじめにいいます、これはポエムです。

2018年もすでに12月の中盤になってきています。今年のMashupAwardsは昨年とは違い一般社団法人MAさんが運営の中心になるということで、どうなることかなと 若干不安に思っていたのですが、12月4日(日)のFESTAが終わって振り返ってみると、これまでとは違った雰囲気も多少ありましたが、これまで同様の満足感があった 期間を過ごせたなと感じています。一番大きな違いを感じたのは個人賞制度だったと思います。(←発明だと思いましたし、これからも続けてもらいたいです)


ここからは自分の話になりますが、今年はイベントが立て込みすぎていて9月以降のほぼ週末は埋まっている状態でした。参加したイベントは

  • おおがきIoT×AIハッカソン by Mashup Awards 2018(参加)
  • LINE BOOT AWARDS 2018 ハッカソン@大阪(参加)
  • Mashup名古屋ハンズオン&ミニハッカソン2018
  • NicoTech 名古屋(運営)
  • OneJapan×Tokai Hackathon(参加はしてないけど…審査側)
  • NRIハッカソン bit.Connect 2018(参加)
  • Startup Weekend Nagoya 13(オーガナイザー)

こんな感じ。正直仕事のイベントも週末にあったりして体力的にかなりつらい。

以前のアドベントカレンダー?でも書いたような感じですが、昨年は名古屋のMA予選のハッカソンなくなるのではという危機があったので急遽イベントの立ち上げなどに 奔走するという感じで始めていましたが、今年は去年の感覚があったのである程度、夏ごろからやるかやらないかということを考えていました。 そんなこんなで結局動き始めたのは9月に近づいた頃になっていました。

今年のMAが始まる頃に名古屋勢(もう一人のMAイスター)にどういう方向がいいかヒアリングしてみたところ、『これまではハッカソンが主体だったけど、もう少しワークショップ的なインプットをしっかりとやって 新規参加者を増やすことも考えたほうがいいかも?』という意見にまとまったような。 ここ数年、私もMashupAwardsのハッカソンだけでなく、ほかのハッカソンにも出ていますが、ハッカソン運営側の共通の課題として新規参加者をどうやって増やしていくかについては、 大きな課題になっているような雰囲気を感じていました。

また、ここ1年ぐらいの方向性としてはハッカソン自体が少し変わってきているのかなと。大きな企業さんのコンテスト内を一定期間で開催し、そのポイント・ポイントで地域による ハッカソンを開催するそんなところでしょうか。これは「ある程度ジャンル縛り」(企業さんが開くものなので当たり前なんですが)のあるものが増えてきたのかなと感じる反面、 具体的なモノを対象にする分インプットがある明示程度しやすく、新規参加者への環境づくりにはいいのかもなあという印象を受けています。あと地域にその技術のコミュニティを育てる効果もあります。 (今年で言うとAmazonさんやAlexaやLINEさんのコンテストなど)

ということで今年の名古屋のハッカソン予選は「Mashup名古屋ハンズオン&ミニハッカソン2018」という形にしてコミュニティでやっているハンズオンを中心にアイデア出しのあたりを行って MashupAwardsの作品締め切りに向けて動いていこうとするイベントに舵をきることにしました。ただ…開催を決めたスケジュールでは他のエリアでもMashupAwards関連のハッカソンが開催されているので 運営をお願いすることはかなり難しい状況ではありました。そのため、他の地域はどちらかというと地域コミュニティが運営をする感じ。名古屋もコミュニティでやるしかないのか…という感じ。

この時点の気持ちを端的に述べるとすれば「運営、正直やべー」

とはいえ、ここでなくすのは残念かなあという気持ちもあり、今年は自分がファシリテーターをしようということに決めました。


当日のトラブルなど…

  • 名古屋工業大学さんの会場をお借りしたのですが、土曜日にやっているはずの学食がやっていない…(夏休み中だった)
  • 近くにある飲食店が火災のため、修繕中だった。(12月10日現在修繕は終了していました)
  • 開催日あたりで台風24号が接近

というように予想外のことが結構多くありました。特に台風に関しては開催中も他のハッカソンを行う会場などが2日間の開催日程を短縮する措置をとっていたりと、 1日目には名古屋までは結構遠い位置にあったのですが中止するなども、天気や交通情報をにらみながら行っていくことような状況でした。 2日目は鉄道の運行がとまるということが早朝の段階でわかったので、今回は1日だけの開催となってしまいました。

ファシリテーターを体験してみて

今回初めてハッカソンのイベント(ミニイベント)ですがをやってみたのですが、やっぱり大変でした。

f:id:ueponx:20181214223449j:plain

自分のやってみた感想としては

  • 結構プレゼンを作ったつもりでもなかなか手が回らないことが多い
  • 初参加の人には話をしても、それだけではなかなか通じないことが多い
  • MashupAwardsは属性が多種多様。いつも参加している人からみると普通と思うようなことでも「?」という表情をされることもある
  • 参加者アイデア出しがなかなかできなくて、進行がなかなかうまくいかない
  • ファシリテーターは参加者の不安そうな表情を見てると参加者にも不安がうつる

心が折れるとまでは行きませんが、なかなか難しい役割だなと思います。

ただ、今回はあまりハッカソンに来ていないような方と数回参加しているという方がいたのである程度バランスが取れた形になったかなということや ワークショップなどがあれば教えてほしいなど話も伺うことができたので、成果としては少しはあったのかなと終わってから少しホッとしています。


終りに

地方ではハッカソンなどのイベントはなかなか開催数が少ないと思います。(多いところもあるけど) 参加するという選択肢以外にも、運営を行ったり、ファシリテーターのようなことをやるというのも面白いかもしれません。 特に運営などを経験するとまた違った視点になれて、プロダクトの作成などのコツなどを学べるのは割といい経験になるかなと思います。

大変だ大変だという感じで内容を書いていた感じもありますが、人とのつながりを感じることのできるのはMashupAwardsのイベントでは特に感じるところです。 たぶんそれは出品される作品がノンジャンルであることや自分のこだわりをそのまま突き通すことのできる土壌があるからなのだと思います。

みなさんも機会があれば、ハッカソンの運営などに協力してみてはどうでしょうか?

f:id:ueponx:20181214223226j:plain

ボヤキ

思うように時間が作れなくて、作品も作れなかったなあ…。 今年一番すごいと思ったパッションはこれです。

f:id:ueponx:20181214223905j:plain

来年はこれに勝てるプロダクトを作りたいです!

JSONを整形して表示したい

ハッカソンやものを作っているときにWEBサービスの入出力がJSONということはあるのですが、 毎回毎回調べていたのでそろそろ自分でまとめておこうと思ったのでメモをとることにしました。

Webサービス化されているものを探してみた

検索してみると以下のようなサービスがありました。

TM - WebTools

tm-webtools.com

JSONの整形以外にも、HTML・XMLの整形、XMLJSON相互変換、BASE64変換、QRコードの生成などがあり意外と便利です。ブログなどに乗せる場合にはこれでもいいかもという感じですが、社内のデータとかはちょっとつかえないですね。

Validationもチェックしてくれます。っていうかそれできないと整形できないか…

f:id:ueponx:20181109142335p:plain

JSONきれい ~JSON整形ツール~

JSONきれい ~JSON整形ツール~ - instant tools

こっちもいくつああるツールの人のようです。文字コードのチェックとかCSV, TSVデータをTEXTの表に変換するなんていうのは便利かもと思います。

f:id:ueponx:20181109142520p:plain

他にもありそうでsが、キリがないのでここまで。

Chrome拡張も探してみた

JSONViewという拡張がありました。

chrome.google.com

f:id:ueponx:20181109143351p:plain

URIにアクセスしてJSONを返すようなRestサービスには便利。

テスト用にJSONを返してくれるような便利なサービスがあるので、それを使ってみます。(会社のデータとかは使っちゃだめですが)

Myjson - A simple json storage and hosting service

上記のURLにアクセスして、すでに準備してあるJSONを入力します。

f:id:ueponx:20181109144533p:plain

下にある【SAVE】ボタンをクリックすると入力されたJSONが返されるURIが発行されます。

f:id:ueponx:20181109144356p:plain

発行されたURIにアクセスすると先程のChrome拡張が有効化されていればへ整形された表示となります。

f:id:ueponx:20181109145105p:plain

他にもJSONを返すサービスは以下もあります。JSONファイルの説明やサンプルコードなどもかいてあるので勉強にはおすすめだと思います。

最短30秒でJSON形式のWEB APIを公開 | JSON OKIBA

Visual Studio Codeでの整形

あとはエディタですが、最近はVisualStudioCodeを使用することが多いのでそちらで整形してみます。以下の記事を参考にしましたが、バージョンアップされて表現などが変わっているようですが、誤差の範囲です

http://blog.snowcait.info/2016/07/09/format-json-on-visual-studio-code/

JSONモードにしておいて(ウインドウの右下の部分がプレーンテキストのモードでは駄目)

f:id:ueponx:20181109145827p:plain

マウスの右クリックをしてメニューを開き、メニューから【ドキュメントのフォーマット】を選択する(またはキーボードのショートカットで【Shift+Alt+F】を押す)と…

f:id:ueponx:20181109150049p:plain

このように整形されます。便利! (一応【Ctrl+z】で元に戻せます。)

f:id:ueponx:20181109150301p:plain

これで編集中の整形は可能なのですが、自動整形する機能もVisualStudioCodeにはあるようです。その場合には以下を参照して作業を行ってみます。

qiita.com

メニューから【ファイル】→【基本設定】→【設定】を選択します。またはキードードで【Ctrl+,(カンマ)】を押します。

f:id:ueponx:20181109151356p:plain

すると以下のようなユーザ設定のタブが表示されます。

f:id:ueponx:20181109152004p:plain

続いて【設定の検索」の入力ボックスからformatonを入力して検索してみます。すると選択肢が絞られていきます。

f:id:ueponx:20181109152107p:plain

表示された画面内でEditor.formatOnXXXのチェックボックスをクリックすると設定が有効化されます。昔はここからテキスト編集だったのに!全然違ってる!

必要そうなのは以下の3つぐらいかなと思います。このあたりの選択は負荷は上がるので個人の判断かなと思います。

  • Editor.FormatOnPaste
  • Editor.FormatOnPaste
  • Editor.FormatOnType

チェックボックスにチェックを入れてみます。

f:id:ueponx:20181109153056p:plain

ペーストすると整形されるはずなので、

f:id:ueponx:20181109153418p:plain

上記のようなテキストを一度カット&ペーストしてみます。

f:id:ueponx:20181109153449p:plain

自動整形できました!やばい、VisualStudioCode素敵すぎる。

LinuxCLIでもやってみたい。

デバックのときなどでCURLコマンドを使用してでてきたJSONも整形されていると嬉しいなあということはよくあります。実はpythonがインストールされていればワンライナーで書くことができるようです。

$ echo '{"json":"obj"}' | python -m json.tool
   {
        "json": "obj"
    }

くっそ便利。なんでこんなことおしえてくれねーんだよ。毎回pythonで変換するコード書いてたよ…くっそー。

部分の抜粋としてはこんな感じ(一回Dictionary型にしてから整形している。)

with outfile:
        json.dump(dict, outfile, sort_keys=True,
                  indent=4, separators=(',', ': '))
        outfile.write('\n')

書いている時間返してほしい…

ほかにも

  • input.jsonJSONを整形して標準出力で出力する場合
$ python -m json.tool input.json
  • input.jsonJSONを整形してoutput.jsonに出力する場合
$ python -m json.tool input.json output.json

なんていうのもできるようです。いろいろ自分が残念に思えてなりません。

Linuxには更に素敵なCLIツールがある

JQというCLIツールが有名のようです。ハイライトやGrepなどのフィルタリングもできるとのこと。サイトにはWindowsにもOSXも動作するようです。

jq Manual (development version)

f:id:ueponx:20181109155746p:plain

$ echo '{"json":"obj"}' | jq '.' -C | less -R`
   {
        "json": "obj"
    }

Webでのオンラインテストサイト準備されています。

f:id:ueponx:20181109163423p:plain

Windowsのcmdで動かしてみましたが、JSONの整形はされるけどカラーハイライトなどはカラーコードが出てくるだけでかなり残念な感じ。WindowsでのJQはやめておいたほうがいい状況です。

f:id:ueponx:20181109161624p:plain

終わりに

いろいろ知らないことが多かったなあ。一度ちゃんと学んだほうが時間短縮できるのでインプットがんばります。


/* -----codeの行番号----- */