Quantcast
Channel: mattintosh note
Viewing all 878 articles
Browse latest View live

mpv でギャップレス再生したい

$
0
0

最近、曲間の継ぎ目が無い音楽をほとんど聞いてなかったけど、前の例大祭で買った FELT さんの Rebirth Story III に収録されている Puppet in the Dark(ディスク2の2曲目と3曲目)がそれだった。

前まで使っていた mplayerはギャップレス再生機能は無いっぽかったけど、mpv のマニュアルを読んでみたら --gapless-audio=<no|yes|weak>で指定できた。

mpv --gapless-audio=yes *.m4a

ただ、これだけでは NASから読んでるせいもあるかもしれないが、継ぎ目が消えない。--audio-bufferオプションでいくらか先読みさせておく。

mpv --gapless-audio=yes--audio-buffer=2 *.m4a

mpv.conf に書いておいてもよさそう。

ところで、Nero AAC Codec を使ってエンコードすると、iTunSMPB というタグが入るけど、ギャップレス再生で使うものらしい。へー。


Ubuntu Linux で qaac.exe を使って AAC/ALAC にエンコードする

$
0
0

脱 Nero AAC Enc を目指して SoXとか色々使いつつもなんか違うなぁ〜と試行錯誤。(そもそも libav の aacコーデックが好きじゃないなら何やっても無駄じゃ…)

もう諦めてやっぱり CoreAudio を使う方向にシフト。しかし、ここ1年はもっぱらペンギン属で林檎マシンを起動することもなくなったのでエンコードのために林檎マシンを起動するのが面倒くさい。ここはなんとか Linux機でどうにかしたいところだが、LinuxiTunesなんてものはないし、そんなものは自分が生きている間にリリースされるかどうかもわからない。

だがしかし、手間は少しかかるものの、Linuxでも CoreAudio を使って AACを作成することはできる。

  1. WINE と 7z(p7zip)のインストール
  2. iTunes6464.exe の入手
  3. AppleApplicationSupport64.msiの抽出
  4. 各種 dll の抽出
  5. qaac64.exe の入手
apt-get install wine p7zip

CoreAudioToolbox.dll などの抽出

その前に 32-bit 版と 64-bit 版の qaac はどちらが良いのか?

自分の環境では、64-bit 版の方が AACエンコードが 2.5倍早かった。(マジで)

なので 64-bit 版をベースに記載する。なお、iTunes6464Setup.exe には 32-bit 版のライブラリも含まれているので 64-bit 版の iTunesをダウンロードしておけばどちらにも対応ができる。

7z でまずは AppleApplicationSupport64.msiを取り出す。

7z e iTunes6464Setup.exe AppleApplicationSupport64.msi

次に、ライブラリだけを取り出す。いくつか出力されるのでここでは出力先を AAS64とする。

※シェルが苦手で、コマンドラインからライブラリのファイル名を変更したりするのが難しい場合は msiexec /a AppleApplicationSupport64.msi /qnMSIパッケージをインストールしてしまった方が楽。

7z e -oAAS64 AppleApplicationSupport.msi \*.dll

ここで出てきたライブラリは頭に x64_AppleApplicationSupport_が付いているのでこれを取り除く必要がある。ここではシェルの置換展開を使ってファイル名の頭の x64_AppleApplicationSupport_だけを取り除く。

cd AAS64
for f in x64_*.dll; domv${f}${f##*_}; done

置換展開が使えない場合は何らかのコマンドを併用して x64_AppleApplicationSupport_を取り除くか、手作業でリネームする。_を区切り文字として cutを使った例を載せておく。

for f in x64_*.dll; domv${f}`echo${f}| cut -d_ -f3`; done

プレフィックスを取り除いたダイナミックライブラリの種類。

  • ApplePushService.dll
  • AppleVersions.dll
  • ASL.dll
  • AVFoundationCF.dll
  • CFNetwork.dll
  • CoreADI.dll
  • CoreAudioToolbox.dll
  • CoreFoundation.dll
  • CoreGraphics.dll
  • CoreLSKD.dll
  • CoreMedia.dll
  • CoreText.dll
  • CoreVideo.dll
  • Foundation.dll
  • icudt49.dll
  • JavaScriptCore.dll
  • libcache.dll
  • libdispatch.dll
  • libexslt.dll
  • libicuin.dll
  • libicuuc.dll
  • libtidy.dll
  • libxml2.dll
  • libxslt.dll
  • main.dll
  • MediaAccessibility.dll
  • objc.dll
  • pthreadVC2.dll
  • QuartzCore.dll
  • SafariTheme.dll
  • SQLite3.dll
  • WebKit.dll
  • WebKitQuartzCoreAdditions.dll
  • WTF.dll
  • YSCrashDump.dll
  • YSUtilities.dll
  • zlib1.dll

これらのダイナミックライブラリを qaac64.exe と同じディレクトリに入れておくか、C:\windows\system32に相当する ${WINEPREFIX}/drive_c/windows/system32(一般的に ~/.wine/drive_c/windows/system32)に入れておけばよい。

WINE で qaac を使うための準備

https://sites.google.com/site/qaacpage/の cabinet から qaac を入手する(執筆時点での最新版は qaac_2.59.zip)。

64-bit 版だけを取り出す。

7z e -oqaac qaac_2.59.zip qaac_2.59/x64/\*

先ほどのダイナミックライブラリを移動またはコピー。

cp AAS64/*.dll qaac

試しに実行。qaac のバージョンと CoreAudioToolbox のバージョンが出力されれば使用可能。もし、ERROR: CoreAudioToolbox.dll: Module not found.のようなメッセージが出るのであればライブラリが呼び出せていない。

wine qaac/qaac64.exe --check
qaac 2.59, CoreAudioToolbox 7.9.9.6 libsoxconvolver 0.1.0 libsoxr-0.1.1

qaac.exe を実行すると WINE の fixme メッセージが出るため WINEDEBUG=fixme-allしておくといいかもしれない。

export WINEDEBUG=fixme-all

qaac64として呼び出せるように ~/.bashrcに alias を追記。--threadingは常用だし入れておいて問題ないと思う。

alias qaac64='WINEDEBUG=fixme-all wine ~/Applications/qaac_2.59/x64/qaac64.exe --threading'

CUE シートを使った AACエンコード

cdrdao、toc2cue で作成した CUE シートから AACを作成する。cdrdao で作成したバイナリはデフォルトではビッグエンディアンになっているので s16bの指定が必要になる(忘れると砂嵐というかホワイトノイズ)。また、toc2cue で作成した CUE シートは(恐らく)UTF-8なので --text-codepage 65001を指定しないと ERROR: 80004001: mlang->DetectCodepageInIStream(0, GetACP(), stream, encoding, &nscores)となる。CUE シートはカレントディレクトリになくてもよい。

qaac64 --raw--raw-format s16b --text-codepage65001 album.cue

アルバムをトラックごとに分割しない場合は --concatオプションを併用する。

qaac64 --raw--raw-format s16b --text-codepage65001--concat album.cue

Mac OSで afconvert を使ってたときも思ったけど、品質の設定がわかりづらい。--tvbr127が最も高品質だが、実際、内部ではある程度決められた段階の値に丸められる。--abrなどは 0を指定すると最高となり、最大ビットレートは自動的に選択される。--quality0が低品質で 2が高品質だが、ファイルサイズは 2の高品質の方が小さくなる。

リサンプル

44.1kHz -> 48kHz などのリサンプルは --rate48000を指定する。--native-resamplerオプションで品質を指定することができ、bats,127が最高品質(12796に丸められる?)。このオプションはスペースではなく、=で繋がなければならない。

qaac64 --rate48000--native-resampler=bats,127 infile.wav

cdrdao、toc2cue で抽出したオーディオ CD の最高品質変換だとこんなところだろうか。

qaac64 \--threading\--raw\--raw-format s16b \--text-codepage65001\--cvbr0\--quality2\--rate48000\--native-resampler=bats,127\
    album.cue

品質比較

オリジナルの CD 品質の WAV ファイル。

f:id:mattintosh4:20160828001143p:plain

デフォルトの設定でエンコードしたもの。これは暗黙的に --quality 2。(TVBR q91, Quality 96)

f:id:mattintosh4:20160828001236p:plain

--quality 0。(TVBR q91, Quality 32)

f:id:mattintosh4:20160828001639p:plain

--quality 0--quality 2(デフォルト)は並べてみるとわかりづらいが、重ねて見ると --quality 0の方がデータが損失している。

f:id:mattintosh4:20160828003945g:plain

スクリプト

多分まだ書いてる途中。

問題点

--fname-format内で ${artist}${album}といったタグが呼び出せない。唯一、呼び出せるのは ${track}${tracknumber}くらい?

仕方ないのでシェル側で埋め込むしかない。

qaac 2.59 ヘルプ

qaac 2.59 Usage: qaac [options] infiles.... "-" as infile means stdin. On ADTS/WAV output mode, "-" as outfile means stdout. Main options: --formats Show available AAC formats and exit -a, --abr <bitrate> AAC ABR mode / bitrate -V, --tvbr <n> AAC True VBR mode / quality [0-127] -v, --cvbr <bitrate> AAC Constrained VBR mode / bitrate -c, --cbr <bitrate> AAC CBR mode / bitrate For -a, -v, -c, "0" as bitrate means "highest". Highest bitrate available is automatically chosen. For LC, default is -V90 For HE, default is -v0 --he HE AAC mode (TVBR is not available) -q, --quality <n> AAC encoding Quality [0-2] --adts ADTS output (AAC only) --no-smart-padding Don't apply smart padding for gapless playback. By default, beginning and ending of input is extrapolated to achieve smooth transition between songs. This option also works as a workaround for bug of CoreAudio HE-AAC encoder that stops encoding 1 frame too early. Setting this option can lead to gapless playback issue especially on HE-AAC. However, resulting bitstream will be identical with iTunes only when this option is set. -d <dirname> Output directory. Default is current working dir. --check Show library versions and exit. -A, --alac ALAC encoding mode -D, --decode Decode to a WAV file. --caf Output to CAF file instead of M4A/WAV/AAC. --play Decode to a WaveOut device (playback). -r, --rate <keep|auto|n> keep: output sampling rate will be same as input if possible. auto: output sampling rate will be automatically chosen by encoder. n: desired output sampling rate in Hz. --lowpass <number> Specify lowpass filter cut-off frequency in Hz. Use this when you want lower cut-off than Apple default. -b, --bits-per-sample <n> Bits per sample of output (for WAV/ALAC only) --no-dither Turn off dither when quantizing to lower bit depth. --peak Scan + print peak (don't generate output file). Cannot be used with encoding mode or -D. When DSP options are set, peak is computed after all DSP filters have been applied. --gain <f> Adjust gain by f dB. Use negative value to decrese gain, when you want to avoid clipping introduced by DSP. -N, --normalize Normalize (works in two pass. can generate HUGE tempfile for large piped input) --drc <thresh:ratio:knee:attack:release> Dynamic range compression. Loud parts over threshold are attenuated by ratio. thresh: threshold (in dBFS, < 0.0) ratio: compression ratio (> 1.0) knee: knee width (in dB, >= 0.0) attack: attack time (in millis, >= 0.0) release: release time (in millis, >= 0.0) --limiter Apply smart limiter that softly clips portions where peak exceeds (near) 0dBFS --start <[[hh:]mm:]ss[.ss..]|<n>s|<mm:ss:ff>f> Specify start point of the input. You specify either in seconds(hh:mm:ss.sss..form) or number of samples followed by 's' or cuesheet frames(mm:ss:ff form) followed by 'f'. Example: --start 4010160s : start at 4010160 samples --start 1:30:70f : same as above, in cuepoint --start 1:30.93333 : same as above --end <[[hh:]mm:]ss[.ss..]|<n>s|<mm:ss:ff>f> Specify end point of the input (exclusive). --delay <[[hh:]mm:]ss[.ss..]|<n>s|<mm:ss:ff>f> Specify amount of delay. When positive value is given, silence is prepended at the begining to achieve specified amount of delay. When negative value is given, specified length is dropped from the beginning. --no-delay Compensate encoder delay by prepending 960 samples of scilence, then trimming 3 AAC frames from the beginning (and also tweak iTunSMPB). This option is mainly intended for resolving A/V sync issue of video. --num-priming <n> (Experimental). Set arbitrary number of priming samples in range from 0 to 2112 (default 2112). Applicable only for AAC LC. --num-priming=0 is the same as --no-delay. Doesn't work with --no-smart-padding. --gapless-mode <n> Encoder delay signaling for gapless playback. 0: iTunSMPB (default) 1: ISO standard (elst + sbgp + sgpd) 2: Both --matrix-preset <name> Specify user defined preset for matrix mixer. --matrix-file <file> Matrix file for remix. --no-matrix-normalize Don't automatically normalize(scale) matrix coefficients for the matrix mixer. --chanmap <n1,n2...> Rearrange input channels to the specified order. Example: --chanmap 2,1 -> swap L and R. --chanmap 2,3,1 -> C+L+R -> L+R+C. --chanmask <n> Force input channel mask(bitmap). Either decimal or hex number with 0x prefix can be used. When 0 is given, qaac works as if no channel mask is present in the source and picks default layout. --no-optimize Don't optimize MP4 container after encoding. --tmpdir <dirname> Specify temporary directory. Default is %TMP% -s, --silent Suppress console messages. --verbose More verbose console messages. -i, --ignorelength Assume WAV input and ignore the data chunk length. --threading Enable multi-threading. -n, --nice Give lower process priority. --sort-args Sort filenames given by command line arguments. --text-codepage <n> Specify text code page of cuesheet/chapter/lyrics. Example: 1252 for Latin-1, 65001 for UTF-8. Use this when bogus values are written into tags due to automatic encoding detection failure. -S, --stat Save bitrate statistics into file. --log <filename> Output message to file. Option for output filename generation: --fname-from-tag Generate filename based on metadata of input. By default, output filename will be the same as input (only different by the file extension). Name generation can be tweaked by --fname-format. --fname-format <string> Format string for output filename. Option for single output: -o <filename> Specify output filename --concat Encodes whole inputs into a single file. Requires output filename (with -o) Option for cuesheet input only: --cue-tracks <n[-n][,n[-n]]*> Limit extraction to specified tracks. Tracks can be specified with comma separated numbers. Hyphen can be used to denote range of numbers. Tracks non-existent in the cue are just ignored. Numbers must be in the range 0-99. Example: --cue-tracks 1-3,6-9,11 -> equivalent to --cue-tracks 1,2,3,6,7,8,9,11 --cue-tracks 2-99 -> can be used to skip first track (and HTOA) Options for Raw PCM input only: -R, --raw Raw PCM input. --raw-channels <n> Number of channels, default 2. --raw-rate <n> Sample rate, default 44100. --raw-format <str> Sample format, default S16L. Sample format spec: 1st char: S(igned) | U(nsigned) | F(loat) 2nd part: Bitwidth Last part: L(ittle Endian) | B(ig Endian) Last part can be omitted, L is assumed by default. Cases are ignored. u16b is OK. Options for CoreAudio sample rate converter: --native-resampler[=line|norm|bats,n] Arguments are optional. Without argument, codec default SRC is used. With argument, dedicated AudioConverter is used for sample rate conversion. '--native-resampler' and arguments must be delimited by a '=' (space is not usable here). Arguments must be delimited by a ','(comma). First argument is sample rate converter complexity, and one of line, norm, bats. line: linear (worst, don't use this) norm: normal bats: mastering (best, but quite sloooow) Second argument is sample rate converter quality, which is an integer between 0-127. Example: --native-resampler --native-resampler=norm,96 Tagging options: (same value is set to all files, so use with care for multiple files) --title <string> --artist <string> --band <string> This means "Album Artist". --album <string> --grouping <string> --composer <string> --comment <string> --genre <string> --date <string> --track <number[/total]> --disk <number[/total]> --compilation[=0|1] By default, iTunes compilation flag is not set. --compilation or --compilation=1 sets flag on. --compilation=0 is same as default. --lyrics <filename> --artwork <filename> --artwork-size <n> Specify maximum width or height of artwork in pixels. If specified artwork (with --artwork) is larger than this, artwork is automatically resized. --copy-artwork Copy front cover art(APIC:type 3) from the source. When --artwork is also given, this option is ignored. --chapter <filename> Set chapter from file. --tag <fcc>:<value> Set iTunes pre-defined tag with fourcc key and value. 1) When key starts with U+00A9 (copyright sign), you can use 3 chars starting from the second char instead. 2) Some known tags having type other than UTF-8 string are taken care of. Others are just stored as UTF-8 string. --tag-from-file <fcc>:<path> Same as above, but value is read from file. --long-tag <key>:<value> Set long tag (iTunes custom metadata) with arbitrary key/value pair. Value is always stored as UTF8 string.

Raspberry Pi (ARM) で i386 Linux のバイナリを実行する

$
0
0

Raspberry Piで Nero AAC Codec(neroAacEnc)を使えるようにしてみた。

f:id:mattintosh4:20160911023334p:plain

ただし、激遅である。

QEMUのビルド

Arch Linux ARM で i386バイナリを実行するためにまずは QEMUのビルドから始める。実用性が低いためか、Pacmanにはまだ用意されていない。Raspbian や Ubuntu MATE for Raspberry Piとかでも必要なパッケージをインストールしておけばビルドできる(はず。Ubuntu MATE は確認済み)。Python 2.x 必須。

git clone httpshttp://git.qemu.org/git/qemu.git
mkdir qemu/build
cd qemu/build
../configure --prefix=/opt/local/qemu--target-list=i386-linux-user--python=/usr/bin/python2
make
make install

i386GNU C Library を用意する

i386GNU C Library が必要になるが、ビルドするのが少々面倒。i386Ubuntuなどがあるならそこから引っ張ってくるという手もある。

ld-linux.so.2どっかに無かったかな〜と思って locateしてみたら Chromiumのソースディレクトリに入ってた。格納先のコードを見てみたら、どうやら Chromiumのビルド用にバイナリ一式を引っ張って来るらしい。ということはこれでビルドの手間を省ける。

元々このソースは本家ではなく、Raspberry Piの Arch Linux ARM 用として拾ってきたもの。https://aur.archlinux.org/packages/chromium-dev/に行けば最新版が手に入る。Chromium本家の方(https://chromium.googlesource.com/chromium/src.git/+/master/build/linux/)でもソースは入手できるが、別途、GYP が必要になる。AUR の方はバイナリがそのまま落ちてくるので楽。難点を挙げれば公式も AUR もファイルサイズがでかい。

AUR のソースの場合、install_script.pyを実行すれば chromium/build/linux/debian_wheezy_i386-sysrootが出来るのであとはそれを拝借する。

cd build/linux/sysroot_scripts
python2 install_script.py --arch i386

本家の方は GYP があれば恐らく AUR と同じようにバイナリが落ちてくるんだろうけど、そもそも install-sysroot.pyhttps://chromium.googlesource.com/chromium/src/build/+/master/linux/sysroot_scripts/install-sysroot.py)にバイナリのダウンロードに必要な URL が書かれているのでそれを使った方が手っ取り早いし低コスト。

install-sysroot.py内の subprocess.callに合わせて書くとこんな感じになる。こちらと AUR の方では i386sysrootの間が -_という違いがあるのでパス補完を使わない人は注意した方がいいかもしれない。

curl --fail--retry3-L-O'https://commondatastorage.googleapis.com/chrome-linux-sysroot/toolchain/24f935a3d8cdfcdfbabd23928a42304b1ffc52ba/debian_wheezy_i386_sysroot.tgz'

展開してあとは qemu-i386 -L /path/to/debian_wheezy_i386_syrootとでもしておけばよい。

mkdir-p debian_wheezy_i386_sysroot
tar xf debian_wheezy_i386_sysroot.tgz -C debian_wheezy_i386_sysroot

ツールチェインを切り替えることはあまり無いので自分の場合は aliasでツールチェインを固定している。-Lオプション以外に QEMU_LD_PREFIX環境変数を使う方法もある。

alias qemu-i386="/opt/local/qemu/bin/qemu-i386 -L /opt/local/debian_wheezy_i386_sysroot"

今回、Raspberry Pii386のプログラムを実行したかったのは CD の取り込みから WAV 抽出まで自動化したのに、AACへの変換で困っていたから。Libavcodecなんかのフリーの AACコーデックだと音質があまり良くない(気がする)。本当は qaac で Appleの CoreAudio を使いたかったのだけど、Raspberry Pii386の WINE を実行できる環境を構築するにはまだ時間が足りない。

Raspberry Pi世界累計出荷台数1,000万台突破おめでとう!!

Arch Linux ARM on Raspberry Pi で LXC を使って Ubuntu を4台同時起動してみる

$
0
0

最近、仮想化で遊んでます。Docker 前から気になってるんだけど………LXC(LinuX Containers)です。

調べてみたら Raspberry Piでも使えるので早速トライ。

lxcDebian系の Ubuntuを入れるので debootstrapをインストール。Arch Linuxの場合は arch-install-scriptsが必要。

pacman -S lxc debootstrap 

/usr/share/lxc/templates以下はこんな感じ。

コンテナを作ってみる。

sudo lxc-create -t ubuntu -n ubuntu01

暫く放置しておく。最期にデフォルトユーザとパスワードが出力されるので覚えておく。

##
# The default user is 'ubuntu' with password 'ubuntu'!
# Use the 'sudo' command to run tasks as root in the container.
##

ネットワークが使えるように /var/lib/lxc/ubntu01/configを編集する。ホストの Arch Linux ARM では systemd-networkdで既に br0は作成してある。

# Template used to create this container: /usr/share/lxc/templates/lxc-ubuntu# Parameters passed to the template:# For additional config options, please look at lxc.container.conf(5)# Uncomment the following line to support nesting containers:#lxc.include = /usr/share/lxc/config/nesting.conf# (Be aware this has security implications)# Common configuration
lxc.include = /usr/share/lxc/config/ubuntu.common.conf

# Container specific configuration
lxc.rootfs = /var/lib/lxc/ubuntu01/rootfs
lxc.rootfs.backend = dir
lxc.utsname = ubuntu01
lxc.arch = armhf

# Network configuration#lxc.network.type = empty
lxc.network.type = veth
lxc.network.link = br0
lxc.network.flags = up
lxc.network.ipv4 = 192.168.1.123/24
lxc.network.ipv4.gateway = 192.168.1.1
lxc.network.name = eth0

コンテナを起動する。

sudo lxc-start-n ubuntu01

ssh -Xで直接コンテナに接続して glxgearsを動かしてみたところ。30 fps以上出るし母艦の Raspberry Piにも余力がまだある。

f:id:mattintosh4:20160911163303p:plain

lxc-copy -n ubuntu01 -N ubuntu0Xでコンテナを複製してみた。ご丁寧に rootfs/etc/hostnamerootfs/etc/hostsも書き換えてくれるらしい。(ただし、configlxc.network.ipv4は変わらない)

Ubuntuのコンテナを複製して4台同時起動してみた。

f:id:mattintosh4:20160911191855p:plain

Raspberry Pi 3 一台で複数の OS が起動できるし、ネットワークインターフェイスも個別に設定が出来るから5〜6人ならそれぞれに仮想マシンを用意させてあげることができそう。lxc-createしてから少し時間はかかるけど時間あるときに作っておいてあとは lxc-copyで複製すればいいかな。

なんか IP が2つ割り当たっていて NICの設定を間違っているような気がするので追々調整する…。


DHCPが有効だとこれだけでいいっぽい。固定 IP にしようとすると IP が二つ割り当てられるんだけどどう設定するんだろ。

lxc.network.type = macvlan
lxc.network.link = br0

↑コンテナの中の /etc/network/interfaces編集するだけだった…。

auto eth0
iface eth0 inet static
    address 192.168.1.123
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 8.8.8.8 8.8.4.4 192.168.1.1

ホスト側から設定ファイル修正出来るのも簡単でいいなぁ…。

Arch Linuxの場合はインターフェイスが起動しないので lxc.network.flags = upにしとく。

lxc.network.type = macvlan
lxc.network.link = br0
lxc.network.flags = up

んで ipコマンド。まだやってないけど /etc/systemd/networkに設定ファイル置いておけば起動するだろう。

ip a add 192.168.1.234/24 dev eth0
ip r add default via 192.168.1.1

mpv と youtube-dl を使ってブラウザを使わずに YouTube 動画を高画質で再生する

$
0
0

mpv にはハードウェア再生支援機能が付いている(ビルドによるんだろうけど)。

まずは対応状況確認。これは機能の段階で Git ソースからビルドしたもの。Ubuntu版は結構バージョンが古いし、caca が使えなかった。--hwdec=オプションには helpがないが、無効な値を指定すると有効な値を表示してくれる。

$ mpv --vo=help; mpv --hwdec=help
Available video outputs: opengl : Extended OpenGL Renderer vdpau : VDPAU with X11 wayland : Wayland SHM video output xv : X11/Xv vaapi : VA API with X11x11 : X11 (slow, old crap) null : Null video output image : Write video frames to image files caca : libcaca drm : Direct Rendering Manager Invalid value for option hwdec: help Valid values are: no auto yes auto-copy vdpau videotoolbox videotoolbox-copy vaapi vaapi-copy dxva2 dxva2-copy d3d11va d3d11va-copy rpi mediacodec cuda cuda-copy Error parsing option hwdec (option could not be parsed) Setting command line option '--hwdec=help' failed. Exiting... (Fatal error)

vainfoも見ておく。

$ vainfo
libva info: VA-API version 0.39.2 libva info: va_getDriverName() returns 0 libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so libva info: Found init function __vaDriverInit_0_39 libva info: va_openDriver() returns 0 vainfo: VA-API version: 0.39 (libva 1.7.1) vainfo: Driver version: Intel i965 driver for Intel(R) Sandybridge Mobile - 1.7.1 vainfo: Supported profile and entrypoints VAProfileMPEG2Simple : VAEntrypointVLD VAProfileMPEG2Main : VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice VAProfileH264Main : VAEntrypointVLD VAProfileH264Main : VAEntrypointEncSlice VAProfileH264High : VAEntrypointVLD VAProfileH264High : VAEntrypointEncSlice VAProfileH264StereoHigh : VAEntrypointVLD VAProfileVC1Simple : VAEntrypointVLD VAProfileVC1Main : VAEntrypointVLD VAProfileVC1Advanced : VAEntrypointVLD VAProfileNone : VAEntrypointVideoProc

さて、いま使っているマシンは Intel CPU なので vaapi-copyが最も良さそう。--voの方は 60 fps動画で色々試してみて一番滑らかに再生できるものを探す。

ちょうどこれが 60 fpsなので借りてくる。

www.youtube.com

mpv 'https://www.youtube.com/watch?v=OO3UZBwpCLM'--hwdec=vaapi-copy--vo=opengl

ヌルヌル動けばOK。

f:id:mattintosh4:20160919002537p:plain

設定が決まったら ~/.config/mpv/mpv.confに書いておく。

hwdec=vaapi-copy
vo=opengl

mpv は YouTubeの動画もページの URL を指定するだけで再生ができる。これは youtube-dl の機能だが、デフォルトの設定が bestvideo+bestaudio/bestになっているので常に最高品質再生ができる(ブラウザの埋め込みプレイヤーとは大違い)。また、シャッフルやループも mpv 側で設定できる(ブラウザの埋め込みプレイヤーとは大違い。大事なことなので)。一日中ずっと高画質で YouTubeに掲載されている動画を再生し続けたいならこれ以上シンプルなものはないだろう。

もしパワーが足りなくて小さいサイズの動画いい場合は --ytdl-format="[height<480]"としておけば高さ480px以下の動画になるし、--ytdl-format="bestaudio"とすれば動画なしの最高音質オーディオのみ、--ytdl-format="[height<=480]+bestaudio"なら小さい画像で音声だけ最高品質になる。

youtube-dl については著作権関係で使い方によっては色々問題がありそうなのでここではあまり触れないことにするが、ユーザ名とパスワードを指定できるところを見るとプレイリストの再生もできるんだろうか。

とりあえずローカルなら youtube.m3u みたいなファイル作ってそこに URL を1行ごとに貼っておけばよい。ヒーリング・ミュージックを一日中再生することがあるのでこの機能は本当に助かる。

Raspberry Pi で GStreamer(gst-launch)

$
0
0

Raspberry Piでは OpenMAX のライブラリを使うことで高速に H264 エンコードができる。

現時点での Arch Linux ARM の ffmpeg--enable-omx-rpiオプション付きでビルドされていないためエンコーダーに h264_omxが使えない。これは単純に ffmpegをセルフビルドすれば済むが、omxplayer や GStreamer のそれに比べるとまだまだ性能を発揮できていないようにも感じる。

Raspberry Pi用のカメラであれば raspivid で h264 で取り込みが出来るのでそこそこ負荷はかからないが、低価格な USB Web カメラは RAW か MJPEG にしか対応していないためハードウェアエンコードがほぼ必須となってくる。そこで、GStreamer を使って USB 接続した Web カメラの映像を取り込んでみることにした。

使うカメラは Buffalo の BSW20KM11BK。

カメラとマイクへのアクセス権を変更

まず、/dev/video0に特権なしでカメラにアクセスできるようアカウントを videoグループに追加する。

sudo usermod -a-G video $USER

マイクが認識されているか確認する。

arecord -l

ここでカメラのマイクが出てこない場合は特権で実行してみる。

sudo arecord -l

ここで出てくる場合は audioグループに入っていないのでこちらもグループに追加する。

sudo usermod -a-G audio $USER

一旦、ログアウトする。

バイスを確認する

gst-device-monitorでデバイスを確認する。ビデオだけであれば v4l2-ctl --allでも良い。

ssh -Yで接続しているとデバイスモニターが開始できないと怒られる。

gst-device-monitor-1.0
Probing devices... Device found: name : Genius WideCam F100 Analog Stereo class : Audio/Source caps : audio/x-raw, format=(string){ S16LE, S16BE, F32LE, F32BE, S32LE, S32BE, S24LE, S24BE, S24_32LE, S24_32BE, U8 }, layout=(string)interleaved, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-alaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-mulaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; properties: alsa.resolution_bits = 16 device.api = alsa device.class = sound alsa.class = generic alsa.subclass = generic-mix alsa.name = "USB\ Audio"alsa.id = "USB\ Audio"alsa.subdevice = 0 alsa.subdevice_name = "subdevice\ \#0"alsa.device = 0 alsa.card = 0 alsa.card_name = USB_Camera alsa.long_card_name = "KYE\ Systems\ Corp.\ USB_Camera\ at\ usb-3f980000.usb-1.4\,\ high\ speed"alsa.driver_name = snd_usb_audio device.bus_path = platform-3f980000.usb-usb-0:1.4:1.2 sysfs.path = /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.2/sound/card0 udev.id = usb-KYE_Systems_Corp.USBCamera_200901010001-02 device.bus = usb device.vendor.id = 0458 device.vendor.name = "KYE\ Systems\ Corp.\ \(Mouse\ Systems\)" device.product.id = 708c device.product.name = "Genius\ WideCam\ F100" device.serial = KYE_Systems_Corp.USBCamera_200901010001 device.form_factor = webcam device.string = front:0 device.buffering.buffer_size = 352800 device.buffering.fragment_size = 176400 device.access_mode = mmap+timer device.profile.name = analog-stereo device.profile.description = "Analog\ Stereo" device.description = "Genius\ WideCam\ F100\ Analog\ Stereo"alsa.mixer_name = "USB\ Mixer"alsa.components = USB0458:708c module-udev-detect.discovered = 1 device.icon_name = camera-web-usb Device found: name : Monitor of Dummy Output class : Audio/Source caps : audio/x-raw, format=(string){ S16LE, S16BE, F32LE, F32BE, S32LE, S32BE, S24LE, S24BE, S24_32LE, S24_32BE, U8 }, layout=(string)interleaved, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-alaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-mulaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; properties: device.description = "Monitor\ of\ Dummy\ Output" device.class = monitor device.icon_name = audio-input-microphone Device found: name : Dummy Output class : Audio/Sink caps : audio/x-raw, format=(string){ S16LE, S16BE, F32LE, F32BE, S32LE, S32BE, S24LE, S24BE, S24_32LE, S24_32BE, U8 }, layout=(string)interleaved, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-alaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-mulaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; properties: device.description = "Dummy\ Output" device.class = abstract device.icon_name = audio-card Device found: name : USB_Camera class : Video/Source caps : video/x-raw, format=(string)YUY2, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, framerate=(fraction)5/1; video/x-raw, format=(string)YUY2, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, framerate=(fraction)8/1; video/x-raw, format=(string)YUY2, width=(int)800, height=(int)600, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, framerate=(fraction)10/1; video/x-raw, format=(string)YUY2, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; video/x-raw, format=(string)YUY2, width=(int)352, height=(int)288, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; video/x-raw, format=(string)YUY2, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; video/x-raw, format=(string)YUY2, width=(int)176, height=(int)144, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; video/x-raw, format=(string)YUY2, width=(int)160, height=(int)120, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; image/jpeg, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; image/jpeg, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; image/jpeg, width=(int)800, height=(int)600, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; image/jpeg, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; image/jpeg, width=(int)352, height=(int)288, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; image/jpeg, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; image/jpeg, width=(int)176, height=(int)144, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; image/jpeg, width=(int)160, height=(int)120, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)2:4:7:1, framerate=(fraction)30/1; video/x-raw, format=(string)I420, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)I420, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)I420, width=(int)800, height=(int)600, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)I420, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)I420, width=(int)352, height=(int)288, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)I420, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)I420, width=(int)176, height=(int)144, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)I420, width=(int)160, height=(int)120, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)YV12, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)YV12, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)YV12, width=(int)800, height=(int)600, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)YV12, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)YV12, width=(int)352, height=(int)288, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)YV12, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)YV12, width=(int)176, height=(int)144, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)YV12, width=(int)160, height=(int)120, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)BGR, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)BGR, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)BGR, width=(int)800, height=(int)600, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)BGR, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)BGR, width=(int)352, height=(int)288, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)BGR, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)BGR, width=(int)176, height=(int)144, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)BGR, width=(int)160, height=(int)120, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)RGB, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)RGB, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)RGB, width=(int)800, height=(int)600, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)RGB, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)RGB, width=(int)352, height=(int)288, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)RGB, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)RGB, width=(int)176, height=(int)144, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; video/x-raw, format=(string)RGB, width=(int)160, height=(int)120, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1; properties: udev-probed = true device.bus_path = platform-3f980000.usb-usb-0:1.4:1.0 sysfs.path = /sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/video4linux/video0 device.bus = usb device.subsystem = video4linux device.vendor.id = 0458 device.vendor.name = "KYE\\x20Systems\\x20Corp." device.product.id = 708c device.product.name = USB_Camera device.serial = KYE_Systems_Corp.USBCamera_200901010001 device.capabilities = :capture: device.api = v4l2 device.path = /dev/video0 v4l2.device.driver = uvcvideo v4l2.device.card = USB_Camera v4l2.device.bus_info = usb-3f980000.usb-1.4 v4l2.device.version = 263190 (0x00040416) v4l2.device.capabilities = 2233466881 (0x85200001) v4l2.device.device_caps = 85983233 (0x05200001)

今回使うカメラは RAW(YUY2/I420/YV12/RGB/BGR)か MJPEG に対応している。Raspberry Pi用のカメラやちょっとお高めのウェブカメラは H264 に対応している。

この中で omxh264encが対応しているのは I420だけ?

ビデオエンコード

まずは入力を接続。qtmuxfaacを使う場合は -e(EOF)がいるんだったかな…。

gst-launch-1.0 -v-e v4l2src device=/dev/video0

次にビデオのフォーマットを指定。

! video/x-raw, format=I420, width=1280, height=720, framerate=30/1

ビデオエンコーダを指定。パーサーも必要。

! omxh264enc ! h264parse

そして Muxer。

! qtmux

最後に sink。

! filesink location=sample.mp4

これを繋げると下のようになる。MP4 は正しく終了しないとコンテナがおかしくなるので timeout -s INTで割り込みをかけて正しく終了させる。

timeout -s INT 10 gst-launch-1.0 -v-e v4l2src device=/dev/video0 \
! video/x-raw, format=I420, width=1280, height=720, framerate=30/1\
! omxh264enc ! h264parse \
! qtmux \
! filesink location=sample.mp4

ビットレートを指定する場合は target-bitrate=control-rate=を使用する。target-bitrate=だけでは動かないので注意。あと、プロパティ間に ,(カンマ)も要らない。(なぜ仕様を合わせないのか…)

omxh264enc target-bitrate=2000000 control-rate=variable
gst-inspect-1.0 omxh264enc
Factory Details: Rank primary + 1 (257) Long-name OpenMAX H.264 Video Encoder Klass Codec/Encoder/Video Description Encode H.264 video streams Author Sebastian Dröge <sebastian.droege@collabora.co.uk> Plugin Details: Name omx Description GStreamer OpenMAX Plug-ins Filename /usr/lib/gstreamer-1.0/libgstomx.so Version 1.2.0 License LGPL Source module gst-omx Source release date 2014-07-23 Binary package GStreamer OpenMAX IL wrapper Plugin (ArchlinuxARM/RPi) Origin URL http://www.archlinuxarm.org/ GObject +----GInitiallyUnowned +----GstObject +----GstElement +----GstVideoEncoder +----GstOMXVideoEnc +----GstOMXH264Enc +----GstOMXH264Enc-omxh264enc Implemented Interfaces: GstPreset Pad Templates: SINK template: 'sink' Availability: Always Capabilities: video/x-raw width: [ 1, 2147483647 ] height: [ 1, 2147483647 ] framerate: [ 0/1, 2147483647/1 ] SRC template: 'src' Availability: Always Capabilities: video/x-h264 width: [ 16, 4096 ] height: [ 16, 4096 ] Element Flags: no flags set Element Implementation: Has change_state() function: gst_omx_video_enc_change_state Element has no clocking capabilities. Element has no URI handling capabilities. Pads: SINK: 'sink' Pad Template: 'sink' SRC: 'src' Pad Template: 'src' Element Properties: name : The name of the object flags: readable, writable String. Default: "omxh264enc-omxh264enc0" parent : The parent of the object flags: readable, writable Object of type "GstObject" control-rate : Bitrate control method flags: readable, writable, changeable only in NULL or READY state Enum"GstOMXVideoEncControlRate" Default: -1, "default" (0): disable - Disable (1): variable - Variable (2): constant - Constant (3): variable-skip-frames - Variable Skip Frames (4): constant-skip-frames - Constant Skip Frames (-1): default - Component Default target-bitrate : Target bitrate (0xffffffff=component default) flags: readable, writable, changeable in NULL, READY, PAUSED or PLAYING state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 quant-i-frames : Quantization parameter for I-frames (0xffffffff=component default) flags: readable, writable, changeable only in NULL or READY state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 quant-p-frames : Quantization parameter for P-frames (0xffffffff=component default) flags: readable, writable, changeable only in NULL or READY state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 quant-b-frames : Quantization parameter for B-frames (0xffffffff=component default) flags: readable, writable, changeable only in NULL or READY state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 inline-header : Inline SPS/PPS header before IDR flags: readable, writable, changeable only in NULL or READY state Boolean. Default: true periodicty-idr : Periodicity of IDR frames (0xffffffff=component default) flags: readable, writable, changeable only in NULL or READY state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 interval-intraframes: Interval of coding Intra frames (0xffffffff=component default) flags: readable, writable, changeable only in NULL or READY state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295

次に faac

gst-inspect-1.0 faac

これって src と sink 逆だと思うんだけど合ってるのか…?

Factory Details: Rank secondary (128) Long-name AAC audio encoder Klass Codec/Encoder/Audio Description Free MPEG-2/4 AAC encoder Author Ronald Bultje <rbultje@ronald.bitfreak.net> Plugin Details: Name faac Description Free AAC Encoder (FAAC) Filename /usr/lib/gstreamer-1.0/libgstfaac.so Version 1.8.3 License LGPL Source module gst-plugins-bad Source release date 2016-08-19 Binary package GStreamer Bad Plugins (Arch Linux) Origin URL http://www.archlinux.org/ GObject +----GInitiallyUnowned +----GstObject +----GstElement +----GstAudioEncoder +----GstFaac Implemented Interfaces: GstPreset Pad Templates: SRC template: 'src' Availability: Always Capabilities: audio/mpeg mpegversion: 4 channels: [ 1, 6 ] rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 } stream-format: { adts, raw } base-profile: { main, lc, ssr, ltp } framed: true audio/mpeg mpegversion: 2 channels: [ 1, 6 ] rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 } stream-format: { adts, raw } profile: { main, lc } framed: true SINK template: 'sink' Availability: Always Capabilities: audio/x-raw format: S16LE layout: interleaved rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 } channels: 1 audio/x-raw format: S16LE layout: interleaved rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 } channels: 2 channel-mask: 0x0000000000000003 audio/x-raw format: S16LE layout: interleaved rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 } channels: 3 channel-mask: 0x0000000000000007 audio/x-raw format: S16LE layout: interleaved rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 } channels: 4 channel-mask: 0x0000000000000107 audio/x-raw format: S16LE layout: interleaved rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 } channels: 5 channel-mask: 0x0000000000000037 audio/x-raw format: S16LE layout: interleaved rate: { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 } channels: 6 channel-mask: 0x000000000000003f Element Flags: no flags set Element Implementation: Has change_state() function: gst_audio_encoder_change_state Element has no clocking capabilities. Element has no URI handling capabilities. Pads: SINK: 'sink' Pad Template: 'sink' SRC: 'src' Pad Template: 'src' Element Properties: name : The name of the object flags: readable, writable String. Default: "faac0" parent : The parent of the object flags: readable, writable Object of type "GstObject" perfect-timestamp : Favour perfect timestamps over tracking upstream timestamps flags: readable, writable Boolean. Default: false mark-granule : Apply granule semantics to buffer metadata (implies perfect-timestamp) flags: readable Boolean. Default: false hard-resync : Perform clipping and sample flushing upon discontinuity flags: readable, writable Boolean. Default: false tolerance : Consider discontinuity if timestamp jitter/imperfection exceeds tolerance (ns) flags: readable, writable Integer64. Range: 0 - 9223372036854775807 Default: 40000000 quality : Variable bitrate (VBR) quantizer quality in % flags: readable, writable Integer. Range: 1 - 1000 Default: 100 bitrate : Average Bitrate (ABR) in bits/sec flags: readable, writable Integer. Range: 8000 - 320000 Default: 128000 rate-control : Encoding bitrate type (VBR/ABR) flags: readable, writable Enum"GstFaacBrtype" Default: 1, "VBR encoding" (1): VBR encoding - VBR (2): ABR encoding - ABR tns : Use temporal noise shaping flags: readable, writable Boolean. Default: false midside : Allow mid/side encoding flags: readable, writable Boolean. Default: true shortctl : Block type encorcing flags: readable, writable Enum"GstFaacShortCtl" Default: 0, "Normal block type" (0): Normal block type - SHORTCTL_NORMAL (1): No short blocks - SHORTCTL_NOSHORT (2): No long blocks - SHORTCTL_NOLONG

ビデオとオーディオを組み合わせる(+いくつかのフィルタ)

フレームレートの変更は videorateフィルタを挟まなくてはならない。色空間の変換は autovideoconvertあたりでいいのだろうか?

clockoverlayは現在の時間を表示する。

ビデオとオーディオを結合する場合は queueを使うことになるが、Muxer へ接続する際に次のエレメントとの間に !は使わない。Muxer などはデフォルトで nameプロパティを持っている(qtmuxなら qtmux0)が、これは上書きできる。

gst-launch-1.0 -v-e\
v4l2src device=/dev/video0 \
! videorate ! video/x-raw, format=I420, width=1280, height=720, framerate=15/1 ! clockoverlay \
! omxh264enc ! h264parse ! queue ! m. \
alsasrc device=hw:0 ! audio/x-raw, format=S16LE, rate=48000, channels=2\
! faac ! aacparse ! queue ! m. \
qtmux name=m \
! filesink location=sample.mp4

この辺はスクリプトにして変数使ったほうがいいかもしれない。

VIDEO_SOURCE="v4l2src device=/dev/video0"VIDEO_SOURCE_FORMAT="video/x-raw, format=I420, width=1280, height=720, framerate=30/1"VIDEO_ENC="omxh264enc ! h264parse"AUDIO_SOURCE="alsasrc device=hw:0"AUDIO_SOURCE_FORMAT="audio/x-raw, format=S16LE, rate=48000, channels=2"AUDIO_ENC="faac ! aacparse"MUXER="qtmux"SINK="filesink location=sample.mp4"

gst-launch-1.0 -v-e\${VIDEO_SOURCE} ! ${VIDEO_SOURCE_FORMAT} ! ${VIDEO_ENC} ! queue ! qtmux0. \${AUDIO_SOURCE} ! ${AUDIO_SOURCE_FORMAT} ! ${AUDIO_ENC} ! queue ! qtmux0. \${MUXER}\
! ${SINK}

どっかにキューをもっと綺麗にまとめる書き方してたサイトがあったけどどこだっけ…。


Armadillo の解説サイトを読ませてもらったけどあれがなかったら覚えられなかったくらいわかりづらい。

あとは tcpserversinkとかも覚えなければ…。ffmpegなら -f v4l2 -i /dev/video0とかでいいのに…ぐぬぬ

Raspberry Pi で GStreamer を使って艦これをフルHDで楽しむ

$
0
0

GStreamer で画面の一部を切り取って拡大したものを他の領域に表示させる方法色々。

ここ最近、GStreamer を弄ってて、RTMP配信はできるようになったけど、画面全体は必要ないよなぁ、と。調べてみたら ximagesrcにはクロッピングオプションがあるようなのでこれを使って Flashの部分だけを切り取ってみる。

Raspberry Pi 3 で動かしている艦これは VNCサーバ上で起動しているのでディスプレイ番号は :1にしている。艦これの表示領域は 800x480 なのでこれをちょいちょい動かして最適な場所を startxstartyで指定する。endxendyはそれぞれの数値に Flashの表示領域分を足したものを指定する。

Raspberry Piではフレームバッファバイスが使えるので fbdevsinkを使えば X が起動していなくても画面に表示させることができる。sync=trueだと遅くなるのでここは sync=falseにしておく。多少のコマ落ちは仕方ない。

x=233y=24w=$((x + 800-1))h=$((y + 480-1))
gst-launch-1.0 -e\
    ximagesrc display-name=:1 show-pointer=falsestartx=${x}starty=${y}endx=${w}endy=${h}\
    ! videoconvert ! videoscale ! video/x-raw, framerate=25/1, width=1920, height=1080, pixel-aspect-ratio=1/1, method=lanczos \
    ! fbdevsink sync=false

そうするとこうなる。記事先頭の写真のような状態になる。

さすがに直接文字を表示しているわけではないので Android版ほど綺麗ではないけど、23 inch くらいのディスプレイなら少し離れればそれほど気にならない。

画像は pngencで取得したもの。

で、操作はどうしてるかっていうと普通の PC から VNCで弄ってるんだな…。ブラウザの拡大機能使えばいいやん…ってなるんだけど。

とりあえず Raspberry Pi単体でクロップと H.264への変換、ALSAのプレイバックオーディオを録音することはできたのであとは用途か。

ximagesinkxvimagesinkは他のマシンのディスプレイも使えるようなので ximagesrcも恐らく他のマシンのディスプレイに接続できるはず。ということはノート PC でゲームをプレイしつつ、エンコードとストリーミング配信は Raspberry Piにやらせることもできそうだ。音声は PulseAudio で拾ってくればなんとかなるだろう。

うーん、Raspberry Piをプロジェクタに接続して Wi-Fiでデータ送ってワイヤレスプロジェクタでも作るか…?


ネットを徘徊していたらゲームのミニマップをサブディスプレイに拡大表示している例があった。なるほど、そういう使い道もあるのか!

Raspberry Piで艦これをYouTube Liveにストリーミング配信する(その他サンプル)

$
0
0

GStreamer を色々弄ってるけどどんどんカオスな状態になっていくのでメモっとく。

「もう OpenMAX 対応したし ffmpegでいいじゃん!」とは言ってはいけない。

YouTube Live に艦隊これくしょんのプレイ動画をストリーミング配信

艦隊これくしょんに限らず、画面の一部分を切り出してストリーミング配信するのでデュアルディスプレイの片方を配信用として使ったりすることもできる。サンプルではテキスト描画や HD 化などのも入れてあるので少々長い。

YouTubeに「キーフレーム間隔長すぎんぞ」って言われるけどどこを弄ればいいのかわからない。(omxh264enc にそんなパラメータあるの?)

パラメータはまだ調整中。

ximagesrc xname="艦隊これくしょん -艦これ- - オンラインゲーム - DMM GAMES"と指定すると艦これのウィンドウだけを拾ってくる(アクティブの場合のみ録画する?)。このウィンドウ名は xwininfoで調べられる。

Raspberry Pi& OpenMAX

  • omxh264enc は x264enc に比べてオプションが少なく、gst-inspect-1.0 omxh264encを読んでもわかりづらい
  • target-bitrate=control-rate=が無いと使えない
  • プロパティの値は 0x000000000xffffffffがデフォルトのようなので printfで10進数に変換させている
  • target-bitrate=0x01000000以上は指定できない(?)
  • alsasrc はチャンネルを指定しないとモノラルになる
  • このサンプルでは VNCサーバを 16-bit で起動しているので ximagesrcの出力が RGB16 になっているが 24-bit で起動しておいた方が良さそう
gst-launch-1.0 -v-e\
flvmux streamable=truename=m ! rtmpsink sync=falselocation="rtmp://a.rtmp.youtube.com/live2/hvd4-k0rb-xp1p-e3ua"\
ximagesrc display-name=:0 show-pointer=falsestartx=$xstarty=$yendx=$((x+800-1))endy=$((y+480-1))\
    ! videoconvert ! video/x-raw, framerate=24000/1001\
    ! videoscale ! video/x-raw, width=1280, height=720, pixel-aspect-ratio=1/1, method=0\
    ! textoverlay font-desc="Droid Sans 8" draw-outline=false shaded-background=truevalignment=top    halignment=left  text="Raspberry Pi 3 - `uname -srm`"\
    ! timeoverlay font-desc="Droid Sans"   draw-outline=false shaded-background=truevalignment=bottom halignment=right \
    ! videoconvert ! omxh264enc control-rate=variable target-bitrate=$(printf'%d' 0x00ffffff) ! h264parse config-interval=4 ! queue ! m. \
alsasrc buffer-time=$((1*1000*1000)) ! audio/x-raw, channels=2 ! faac ! aacparse ! queue ! m.

http://cdn-ak.f.st-hatena.com/images/fotolife/m/mattintosh4/20161009/20161009190121_original.png?1476007523

X86_64 & VAAPI

艦これの画面は800×480ピクセルだが、720p に変換して YouTube Live に投げる。H.264への変換は VAAPI を使うことで負荷を少なくする。H.264への変換はデバイスによってハードウェアエンコードが可能だが、それぞれ名称やプロパティが異なるのでネットを徘徊して情報を集める場合は予めその辺に注意しておく必要がある。(例えば Raspberry Piなら omxh264enc

PulseAudio のデバイスが正しく選択されない場合は pavucontrolを使うことで GUIでデバイスを変更することができる。

gst-launch-1.0 -e\
  flvmux name=m ! rtmpsink sync=falselocation="rtmp://a.rtmp.youtube.com/live2/STREAM-KEY"\
  ximagesrc display-name=:0startx=${x}starty=${y}endx=$((x+800-1))endy=$((y+480-1)) show-pointer=false\
  ! video/x-raw, framerate=30/1\
  ! videoscale ! video/x-raw, width=1280, height=720, pixel-aspect-ratio=1/1\
  ! textoverlay font-desc="Droid Sans"halignment=left  valignment=top    shaded-background=truetext="$(set -- $(lscpu | grep"^Model name:"); shift2; echo$*)"\
  ! timeoverlay font-desc="Droid Sans"halignment=right valignment=bottom shaded-background=true\
  ! videoconvert ! video/x-raw, format=YV12 \
  ! vaapih264enc rate-control=cbr bitrate=$((4*1024))cabac=true max-bframes=2 ! queue ! m. \
  pulsesrc volume=1 buffer-time=1000000\
  ! audio/x-raw, format=S16LE, rate=44100, channels=2 ! voaacenc ! aacparse ! queue ! m.

http://cdn-ak.f.st-hatena.com/images/fotolife/m/mattintosh4/20161009/20161009003540_original.png?1475941043

Screen Shot & Interval/Time Lapse

スナップショットとして1枚記録する。

gst-launch-1.0 ximagesrc ! videoconvert ! pngenc snapshot=true compression-level=9 ! filesink location=screenshot.png

毎秒撮影。

gst-launch-1.0 ximagesrc ! video/x-raw, framerate=1/1 ! videoconvert ! pngenc snapshot=false compression-level=9 ! multifilesink location=%04d.png

エンコード

multifilesrcを使って複数の画像ファイルを入力に指定する。入力タイプおよびフレームレートは caps=で指定する。ポイントとしては PNGをエンコーダの入力形式に合うよう正しく変換すること(ここでは sRGB から I420 の変換を行っている)。進捗が確認できないので ffmpegで変換した方がいいかもしれない。

gst-launch-1.0 multifilesrc location="%04d.png"index=0caps="image/png, framerate=5/1" ! pngdec ! videoconvert ! video/x-raw, format=I420 ! vaapih264enc ! qtmux ! filesink location=video.mp4

http://cdn-ak.f.st-hatena.com/images/fotolife/m/mattintosh4/20161009/20161009195053_original.png?1476010274

音楽 CD の再生と取り込み

  • mode=1はディスク全体を指定する
  • cdda://{TRACK}または track=を指定しなかった場合のデフォルトは 1
  • cdda://書式では mode=が指定できない(?)

再生

■ cdda プロトコルによる再生

(内部的に cdparanoiasrc を呼び出してる?)

gst-inspect-1.0 cdda:// ! autoaudiosink
gst-inspect-1.0 cdda://3 ! autoaudiosink

■ cdiocddasrc による再生

gst-inspect-1.0 cdiocddasrc mode=1 ! autoaudiosink
gst-inspect-1.0 cdiocddasrc track=3 ! autoaudiosink

http://cdn-ak.f.st-hatena.com/images/fotolife/m/mattintosh4/20161009/20161009015614_original.png?1475945927

■ cdparanoiasrc による再生

gst-inspect-1.0 cdparanoiasrc mode=1 ! autoaudiosink
gst-inspect-1.0 cdparanoiasrc track=3 ! autoaudiosink

http://cdn-ak.f.st-hatena.com/images/fotolife/m/mattintosh4/20161009/20161009015612_original.png?1475945854

■ スペクトラグラム 付きで再生する

teeを使って1つを autoaudiosinkへ。もう1つを audioconvertを通して spectrascopeに投げる。

gst-launch-1.0 cdparanoiasrc ! \
  tee   ! queue ! autoaudiosink \
  tee0. ! queue ! audioconvert ! spectrascope shader=8 ! video/x-raw, width=640, height=480 ! ximagesink

http://cdn-ak.f.st-hatena.com/images/fotolife/m/mattintosh4/20161008/20161008174256_original.png

上の例に更にエンコード(ファイル保存)を追加すると以下のようになる。

gst-launch-1.0 cdparanoiasrc track=3 ! \
  tee   ! queue ! autoaudiosink \
  tee0. ! queue ! audioconvert ! spectrascope shader=8 ! video/x-raw, width=640, height=480 ! ximagesink \
  tee0. ! queue ! filesink location=track03.wav

http://cdn-ak.f.st-hatena.com/images/fotolife/m/mattintosh4/20161009/20161009022043_original.png?1475947275

WAV エンコード

gst-launch-1.0 cdparanoiasrc track=1 ! wavenc ! filesink location=track01.wav

http://cdn-ak.f.st-hatena.com/images/fotolife/m/mattintosh4/20161009/20161009020729_original.png?1475946473

DOT ファイルの出力と変換

GST_DEBUG_DUMP_DOT_DIR=が設定されていれば指定されたディレクトリに DOT ファイルが作成される。

GST_DEBUG_DUMP_DOT_DIR=. gst-launch-1.0 [PIPELINE-DESCRIPTION]

Graphvizdotコマンドでも変換できるけど、サイズの指定ができないようなので ImageMagickを使う。フォント名は DOT ファイルに直書きされているので sedなどで好みのものに変換する。

仮にこのファイルを dotconv.shとする。

#!/bin/bash
sed 's|fontname="sans"|fontname="Noto Sans CJK JP"|
     s|fontname="BitStream Vera Sans"|fontname="Noto Sans CJK JP"|
     s|fontname="monospace"|fontname="DejaVu Sans Mono"|
' "$@"
dotconv.sh DOTFILE.dot | convert -density96-format dot - converted.png

Arch Linux ARMのLXCで作成したDebianにlxc-consoleできない

$
0
0
lxc-create -t debian -n debian_1 ---r jessie

configを書き換える。

lxc.network.type = veth
lxc.network.link = br0

コンテナを再起動する。ちなみに lxc-stop -rで再起動だとネットワークの設定が反映されない。

lxc-stop-n debian_1 && lxc-start-n debian_1

で、コンソールに接続しようとするが接続できない。

lxc-console -n debian_1

rootfs/etc/securettyを見ると LXC のコンソールは全て lxc以下にあるらしい。

# LXC (Linux Containers)
lxc/console
lxc/tty1
lxc/tty2
lxc/tty3
lxc/tty4

というわけで -tオプションでなんかやってみる。これでとりあえず接続はできた。

lxc-console -n debian_1 -t0

しかしこっちは繋がらない。

lxc-console -n debian_1 -t1

rootfs/devを見てみるとなんか少ないような。/dev/consoleって無くてもいいんだっけ?

$ ls -l /var/lib/lxc/debian_1/rootfs/dev/
total 8
lrwxrwxrwx 1 root root   13 Sep 14 08:42 fd -> /proc/self/fd
crw-rw-rw- 1 root root 1, 7 Sep 14 08:42 full
crw-rw-rw- 1 root root 1, 3 Sep 14 08:42 null
lrwxrwxrwx 1 root root    8 Sep 14 08:42 ptmx -> pts/ptmx
drwxr-xr-x 2 root root 4096 Sep 14 08:42 pts
crw-rw-rw- 1 root root 1, 8 Sep 14 08:42 random
drwxr-xr-x 2 root root 4096 Sep 14 08:42 shm
lrwxrwxrwx 1 root root   15 Sep 14 08:42 stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root   15 Sep 14 08:42 stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root   15 Sep 14 08:42 stdout -> /proc/self/fd/1
crw-rw-rw- 1 root root 5, 0 Sep 14 08:42 tty
crw-r--r-- 1 root root 4, 1 Oct 10 17:50 tty1
crw-r--r-- 1 root root 4, 2 Oct 10 17:50 tty2
crw-r--r-- 1 root root 4, 3 Oct 10 17:50 tty3
crw-r--r-- 1 root root 4, 4 Oct 10 17:50 tty4
crw-rw-rw- 1 root root 1, 9 Sep 14 08:42 urandom
crw-rw-rw- 1 root root 1, 5 Sep 14 08:42 zero

Ubunturootfs/dev見てもやっぱり Debianは少ない。

$ ls -l /var/lib/lxc/ubuntu16_1/rootfs/dev
total 4
crw-rw---- 1 root   44 10, 175 Oct 10 17:21 agpgart
crw-rw---- 1 root   29 14,   4 Oct 10 17:21 audio
crw-rw---- 1 root   29 14,  20 Oct 10 17:21 audio1
crw-rw---- 1 root   29 14,  36 Oct 10 17:21 audio2
crw-rw---- 1 root   29 14,  52 Oct 10 17:21 audio3
crw-rw---- 1 root   29 14,   7 Oct 10 17:21 audioctl
crw------- 1 root tty   5,   1 Oct 10 17:21 console
lrwxrwxrwx 1 root root      11 Oct 10 17:21 core -> /proc/kcore
crw-rw---- 1 root   29 14,   3 Oct 10 17:21 dsp
crw-rw---- 1 root   29 14,  19 Oct 10 17:21 dsp1
crw-rw---- 1 root   29 14,  35 Oct 10 17:21 dsp2
crw-rw---- 1 root   29 14,  51 Oct 10 17:21 dsp3
lrwxrwxrwx 1 root root      13 Oct 10 17:21 fd -> /proc/self/fd
crw-rw-rw- 1 root root  1,   7 Oct 10 17:21 full
crw-r----- 1 root   15  1,   2 Oct 10 17:21 kmem
brw-rw---- 1 root disk  7,   0 Oct 10 17:21 loop0
brw-rw---- 1 root disk  7,   1 Oct 10 17:21 loop1
brw-rw---- 1 root disk  7,   2 Oct 10 17:21 loop2
brw-rw---- 1 root disk  7,   3 Oct 10 17:21 loop3
brw-rw---- 1 root disk  7,   4 Oct 10 17:21 loop4
brw-rw---- 1 root disk  7,   5 Oct 10 17:21 loop5
brw-rw---- 1 root disk  7,   6 Oct 10 17:21 loop6
brw-rw---- 1 root disk  7,   7 Oct 10 17:21 loop7
crw-r----- 1 root   15  1,   1 Oct 10 17:21 mem
crw-rw---- 1 root   29 35,   0 Oct 10 17:21 midi0
crw-rw---- 1 root   29 14,   2 Oct 10 17:21 midi00
crw-rw---- 1 root   29 14,  18 Oct 10 17:21 midi01
crw-rw---- 1 root   29 14,  34 Oct 10 17:21 midi02
crw-rw---- 1 root   29 14,  50 Oct 10 17:21 midi03
crw-rw---- 1 root   29 35,   1 Oct 10 17:21 midi1
crw-rw---- 1 root   29 35,   2 Oct 10 17:21 midi2
crw-rw---- 1 root   29 35,   3 Oct 10 17:21 midi3
crw-rw---- 1 root   29 14,   0 Oct 10 17:21 mixer
crw-rw---- 1 root   29 14,  16 Oct 10 17:21 mixer1
crw-rw---- 1 root   29 14,  32 Oct 10 17:21 mixer2
crw-rw---- 1 root   29 14,  48 Oct 10 17:21 mixer3
crw-rw---- 1 root   29 31,   0 Oct 10 17:21 mpu401data
crw-rw---- 1 root   29 31,   1 Oct 10 17:21 mpu401stat
crw-rw-rw- 1 root root  1,   3 Oct 10 17:21 null
crw-r----- 1 root   15  1,   4 Oct 10 17:21 port
lrwxrwxrwx 1 root root       8 Oct 10 17:17 ptmx -> pts/ptmx
drwxr-xr-x 2 root root    4096 Oct 10 17:17 pts
lrwxrwxrwx 1 root root       4 Oct 10 17:21 ram -> ram1
brw-rw---- 1 root disk  1,   0 Oct 10 17:21 ram0
brw-rw---- 1 root disk  1,   1 Oct 10 17:21 ram1
brw-rw---- 1 root disk  1,  10 Oct 10 17:21 ram10
brw-rw---- 1 root disk  1,  11 Oct 10 17:21 ram11
brw-rw---- 1 root disk  1,  12 Oct 10 17:21 ram12
brw-rw---- 1 root disk  1,  13 Oct 10 17:21 ram13
brw-rw---- 1 root disk  1,  14 Oct 10 17:21 ram14
brw-rw---- 1 root disk  1,  15 Oct 10 17:21 ram15
brw-rw---- 1 root disk  1,  16 Oct 10 17:21 ram16
brw-rw---- 1 root disk  1,   2 Oct 10 17:21 ram2
brw-rw---- 1 root disk  1,   3 Oct 10 17:21 ram3
brw-rw---- 1 root disk  1,   4 Oct 10 17:21 ram4
brw-rw---- 1 root disk  1,   5 Oct 10 17:21 ram5
brw-rw---- 1 root disk  1,   6 Oct 10 17:21 ram6
brw-rw---- 1 root disk  1,   7 Oct 10 17:21 ram7
brw-rw---- 1 root disk  1,   8 Oct 10 17:21 ram8
brw-rw---- 1 root disk  1,   9 Oct 10 17:21 ram9
crw-rw-rw- 1 root root  1,   8 Oct 10 17:21 random
crw-rw---- 1 root   29 35,  64 Oct 10 17:21 rmidi0
crw-rw---- 1 root   29 35,  65 Oct 10 17:21 rmidi1
crw-rw---- 1 root   29 35,  66 Oct 10 17:21 rmidi2
crw-rw---- 1 root   29 35,  67 Oct 10 17:21 rmidi3
crw-rw---- 1 root   29 14,   1 Oct 10 17:21 sequencer
lrwxrwxrwx 1 root root       8 Oct 10 17:42 shm -> /run/shm
crw-rw---- 1 root   29 35, 128 Oct 10 17:21 smpte0
crw-rw---- 1 root   29 35, 129 Oct 10 17:21 smpte1
crw-rw---- 1 root   29 35, 130 Oct 10 17:21 smpte2
crw-rw---- 1 root   29 35, 131 Oct 10 17:21 smpte3
crw-rw---- 1 root   29 14,   6 Oct 10 17:21 sndstat
lrwxrwxrwx 1 root root       4 Oct 10 17:21 stderr -> fd/2
lrwxrwxrwx 1 root root       4 Oct 10 17:21 stdin -> fd/0
lrwxrwxrwx 1 root root       4 Oct 10 17:21 stdout -> fd/1
crw-rw-rw- 1 root tty   5,   0 Oct 10 17:21 tty
crw------- 1 root tty   4,   0 Oct 10 17:21 tty0
crw------- 1 root tty   4,   1 Oct 10 17:41 tty1
crw------- 1 root tty   4,   2 Oct 10 17:41 tty2
crw------- 1 root tty   4,   3 Oct 10 17:41 tty3
crw------- 1 root tty   4,   4 Oct 10 17:41 tty4
crw------- 1 root tty   4,   5 Oct 10 17:41 tty5
crw------- 1 root tty   4,   6 Oct 10 17:41 tty6
crw------- 1 root tty   4,   7 Oct 10 17:21 tty7
crw------- 1 root tty   4,   8 Oct 10 17:21 tty8
crw------- 1 root tty   4,   9 Oct 10 17:21 tty9
crw-rw-rw- 1 root root  1,   9 Oct 10 17:21 urandom
crw-rw-rw- 1 root root  1,   5 Oct 10 17:21 zero

configlxc.devttydir = lxcを追加してみても変化が無いような…。

また今度でいいや(´・ω・`)

Xアプリケーション名からウィンドウIDを取得する

$
0
0
  • 課題:GStreamer の ximagesrc xid=に渡すウィンドウ ID を自動で取得したい(艦これを起動している Google Chromeのウィンドウ ID だけが欲しい)
  • 問題:ウィンドウ ID がころころ変わる
  • 問題:Ubuntu 16.04 の gst-launch-1.0 ximagesrc xname=が何故か効かない

とりあえず xwininfoでウィンドウの名前を調べる。

$ xwininfo

xwininfo: Please select the window about which you
          would like information by clicking the
          mouse in that window.

xwininfo: Window id: 0x740005c "艦隊これくしょん -艦これ- - オンラインゲーム - DMM GAMES"

  Absolute upper-left X:  0
  Absolute upper-left Y:  65
  Relative upper-left X:  0
  Relative upper-left Y:  0
  Width: 1366
  Height: 703
  Depth: 24
  Visual: 0x20
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x22 (installed)
  Bit Gravity State: NorthWestGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsViewable
  Override Redirect State: no
  Corners:  +0+65  -1050+65  -1050-912  +0-912
  -geometry 1366x703+0+36

とりあえずこれでいま艦これを起動している Google Chromeのウィンドウ ID は 0x740005cであることがわかった。しかしこれは毎回ころころ変わってしまうので使い物にならない。

ウィンドウ名は変わることがないので 艦隊これくしょん -艦これ- - オンラインゲーム - DMM GAMESを使うことにする。

X 環境ではウィンドウは親がウィンドウマネージャなので子がある(ウィンドウの枠などが無いところ)。さっき調べたウィンドウ名から子を調べる。

$ xwininfo -name "艦隊これくしょん -艦これ- - オンラインゲーム - DMM GAMES" -children

xwininfo: Window id: 0x740005c "艦隊これくしょん -艦これ- - オンラインゲーム - DMM GAMES"

  Root window id: 0xc1 (the root window) (has no name)
  Parent window id: 0x2b31f74 (has no name)
     1 child:
     0x7600077 (has no name): ()  1366x703+0+0  +0+65

これで子の ID が 0x7600077であることがわかった。あとはこれを適当に取り出せばよい。

xwininfo -name"艦隊これくしょん -艦これ- - オンラインゲーム - DMM GAMES"-children | grep-A1"1 child:" | awk 'NR == 2 { print $1 }'

ここまでわかれば FLASHプレイヤーの表示位置もほぼ固定なので座標も指定できる。

x=276 y=77; gst-launch-1.0 -v ximagesrc show-pointer=false startx=$x starty=$y endx=$((x+800-1)) endy=$((y+480-1)) xid="`xwininfo -name "艦隊これくしょん -艦これ- - オン ラインゲーム - DMM GAMES" -children | grep -A1 "1 child:" | awk 'NR == 2 { print $1 }'`" ! video/x-raw, framerate=30/1 ! videoconvert ! video/x-raw, format=I420 ! vaapih264enc init-qp=22 dct8x8=true cabac=true max-bframes=2 ! h264parse ! flvmux ! filesink location=game.flv

LinuxでLogicool m560のサイドボタンを使う

$
0
0

先日、エレコムのマウスを買った。長年、Microsoftの IntelliMouse Optical を使っていた人間からするとすごく妥協した形なのだけど、生産完了となってしまっては仕方がない。

さて、そのエレコムのマウスだが一言で「最悪」。マウスのカーソルは飛ぶわクリック誤認するわ。特に酷いのはカーソルを左にひねろうとしたときに反応が遅れること。もっと最悪なのが底面のパットの素材が最悪過ぎて粘着剤が剥がれるレベルで湾曲してくること。あと、素材的にも滑りやす過ぎる。ケーブルも癖がつきやすく、質が悪い。あまり製品批判とかはしたくないけどこの製品は価格帯からすると正直酷い。エレコムのマウスを買ったのは人生で3度目だけどすべて期待外れ。そもそもこの会社の設計者と自分の趣向が合っていないのだろう。もう一生買わないと決めた。

んで、ようやく新しいのを買ってきた。もう有線タイプは諦めて無線にした。

ほんとはこっちの方がクリック感がよかったけどちょい高い。

Logicoolのレシーバーは Linuxに挿しても使えるのは知っていたのでそのまま挿してカーソルの動きにも満足。

ところがサイドボタンが効かない。

とりあえず xevでボタンを調べてみた。

$ xev | grep button

そうするとサイドボタンは 1011になっているようだ。以前使っていたマウスではこれらは 89に割り当てられていたようなので Xmodmap を使って変更する。

先に ~/.Xmodmapを作成しておく。

pointer = 1 2 3 4 5 6 7 10 11 9 8

xmodmapにロード。

$ xmodmap - <~/.Xmodmap

これで「戻る」「進む」ボタンが有効になった。

5ボタンマウスならだいたい割り当て同じなもんだと思うけどなんで変わるのかね。そういやこのマウス横スクロールとかもあるからそっち使ってるのか。

ちなみに Logicoolの Unifying の設定は Linuxでは solaarというソフトウェアで設定できるようだ。ボタンの配置などは easystrokeなんかでカスタマイズできるらしい。

Raspberry Pi 3 の無線省電力機能をオフにする

$
0
0

hostapd で無線 LAN アクセスポイント化している Raspberry Pi 3 のワイヤレスパワーマネジメント機能を切ろうと思ってちょっと試してみたら iwconfigだと弾かれるらしい。txpower は使えるんだけどな…。

$ sudo iwconfig wlan0 power off
Error for wireless request "Set Power Management" (8B2C) :
    SET failed on device wlan0 ; Invalid argument.

iwコマンドでは正しく動作する。

$ sudo iw dev wlan0 set power_save off
$ iw dev wlan0 get power_save
Power save: off
$ iwconfig wlan0
wlan0     IEEE 802.11bgn  Mode:Master  Tx-Power=31 dBm   
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Power Management:off

hostapd が起動した後にパワーマネジメント機能を無効にするために /usr/lib/systemd/system/multi-user.target.wants/hostapd.serviceExecStartPost=行を追加する。

[Unit]
Description=Hostapd IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
After=network.target

[Service]
ExecStart=/usr/bin/hostapd /etc/hostapd/hostapd.conf
ExecStartPost=/usr/bin/iw dev wlan0 set power_save off
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

変更を反映させる。

$ sudo systemctl daemon-reload

とりあえずこれだけ知っておけばなんとかなるRaspberry Piのオーディオ設定

$
0
0

いつからだか忘れたけど Arch Linux ARM では /boot/config.txtgpu_mem=64以外何も書かれなくなった。(RPi2 と RPi3 で設定が異なるからだろうか)

んで、音楽を再生しても音が鳴らないことがしばしば。いい加減この辺の設定ちゃんと調べないとなと思ったので調べた。

/boot/config.txt に dtparam=audio=on が無いとそもそも音が鳴らない

サウンドカードを調べる方法は色々あるけど、わかりやすいのは aplay -l

$ aplay -l
aplay: device_list:268: no soundcards found...

サウンドカードが無いと言われます。

aplay -Lも見てみます。

$ aplay -L
null
    Discard all samples (playback) or generate zero samples (capture)
pulse
    PulseAudio Sound Server
default
    Default ALSA Output (currently PulseAudio Sound Server)

PulseAudio はあるので PULSE_SERVER環境変数を使えば他のマシンで音を鳴らすことはできます。が、コレジャナイ。

さて、では dtparam=audio=onって何さ?っていうのは /opt/vc/bin/dtparamで調べることができる。

/opt/vc/bin/dtparam -h audio
audio                   Set to "on" to enable the onboard ALSA audio
                        interface (default "off")

onにするとオンボードALSAオーディオインターフェイスが有効になるよ!」

つまり dtparam=audio=onを設定しない限り、Raspberry PiHDMIやイヤホンジャックから音は鳴らないわけですね。

これを /boot/config.txtに書いて再起動します。

再び aplay -lを見てみると ALSAが使えるようになっているのがわかります。

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 0: ALSA [bcm2835 ALSA], device 1: bcm2835 ALSA [bcm2835 IEC958/HDMI]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
$ aplay -L
null
    Discard all samples (playback) or generate zero samples (capture)
pulse
    PulseAudio Sound Server
default
    Default ALSA Output (currently PulseAudio Sound Server)
sysdefault:CARD=ALSA
    bcm2835 ALSA, bcm2835 ALSA
    Default Audio Device

この辺の設定は /etc/asound.confに書いてある。

amixer cset numid=3 って何さ?

「音が鳴らない時にはこれを試してごらんよ!」と、よく言われる amixer cset numid=3 1とか amixer cset numid=3 2というコマンド。

これ、単体でみるとよくわからんのだが、amixer で色々試してみるとわかる。

$ amixer controls
numid=4,iface=MIXER,name='Master Playback Switch'
numid=3,iface=MIXER,name='Master Playback Volume'
numid=2,iface=MIXER,name='Capture Switch'
numid=1,iface=MIXER,name='Capture Volume'

ふむ。numid=3というのは Master Playback Volume らしい。

ん?なんか違わね?

実は PulseAudio を入れている場合、amixer では PulseAudio のコントロールが出てきてしまう。例えば PulseAudio を使っていない root の場合だと、

$ sudo amixer controls
numid=3,iface=MIXER,name='PCM Playback Route'
numid=2,iface=MIXER,name='PCM Playback Switch'
numid=1,iface=MIXER,name='PCM Playback Volume'
numid=5,iface=PCM,name='IEC958 Playback Con Mask'
numid=4,iface=PCM,name='IEC958 Playback Default'

となり、numid=3は PCM Playback Route となる。つまり、よく見かける cset numid=3というのはこの PCM Playback Route のことを指している。

PulseAudio がインストールされており、なおかつ一般ユーザーで amixer cset numid=3 1とかやると単にボリュームが変わる可能性が高い。ちなみ Switch 系はミュート切り替え用。

では一般ユーザーが PCM Playback Route を操作するにはどうするのか?

それはカードを正しく指定してあげるだけ。

$ amixer -c ALSA controls
numid=3,iface=MIXER,name='PCM Playback Route'
numid=2,iface=MIXER,name='PCM Playback Switch'
numid=1,iface=MIXER,name='PCM Playback Volume'
numid=5,iface=PCM,name='IEC958 Playback Con Mask'
numid=4,iface=PCM,name='IEC958 Playback Default'

さらに amixer contentsを見てみる。

$ amixer -c ALSA contents
numid=3,iface=MIXER,name='PCM Playback Route'
  ; type=INTEGER,access=rw------,values=1,min=0,max=2,step=0
  : values=1
numid=2,iface=MIXER,name='PCM Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=1,iface=MIXER,name='PCM Playback Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=-10239,max=400,step=0
  : values=399
  | dBscale-min=-102.39dB,step=0.01dB,mute=1
numid=5,iface=PCM,name='IEC958 Playback Con Mask'
  ; type=IEC958,access=r-------,values=1
  : values=[AES0=0x02 AES1=0x00 AES2=0x00 AES3=0x00]
numid=4,iface=PCM,name='IEC958 Playback Default'
  ; type=IEC958,access=rw------,values=1
  : values=[AES0=0x00 AES1=0x00 AES2=0x00 AES3=0x00]

numid=3values=1になっているため、アナログオーディオが有効になっている状態。これを HDMIに切り替えるには、

$ amixer -c ALSA cset numid=3 2

とすればよい。

ボリュームやスイッチの操作は以下のように行うことができる。ボリュームに負の値を指定する場合はオプションとして誤認されないよう --を付ける必要がある。

$ amixer --card ALSA cset numid=1 -- -10239 # Mute
$ amixer --card ALSA cset numid=1 400       # Max
$ amixer --card ALSA cset numid=1 mute      # Mute
$ amixer --card ALSA cset numid=1 100%      # Max
$ amixer --card ALSA cset numid=2 0         # Off (Mute)
$ amixer --card ALSA cset numid=2 1         # On

PulseAudio の場合はボリュームの指定方法が少し異なる。

$ amixer contents
numid=4,iface=MIXER,name='Master Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=3,iface=MIXER,name='Master Playback Volume'
  ; type=INTEGER,access=rw------,values=2,min=0,max=65536,step=1
  : values=65536,65536
numid=2,iface=MIXER,name='Capture Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=1,iface=MIXER,name='Capture Volume'
  ; type=INTEGER,access=rw------,values=2,min=0,max=65536,step=1
  : values=65536,65536
$ amixer cset numid=3 0       # Mute
$ amixer cset numid=3 65536   # Max
$ amixer cset numid=3 65536,0 # Left max, Right mute

PulseAudio の場合は pactl set-sink-volume 0 50%などでもボリューム変更ができる。(alsamixerを使った方が楽)

この辺を覚えておけば Raspberry Piで音が鳴らない問題はだいたい解決できるはず。

Raspberry Piの温度とかクロックをモニタリングする

$
0
0

Raspberry Pi 3 にヒートシンクを付けた。千石電商で170円だった。

RPi3にヒートシンク着けた✧٩(◦`꒳´◦)۶✧ #RaspberryPi #RPi

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

実は Raspberry Pi 2 の頃のケースだとコアの位置が違うのと、小さい方のコアの部分に穴が空いてないのでヒートシンクの装着ができないのだった。

オーバークロックとかの状態を見たかったので vcgencmdから色々引っ張り出すものを書いてみた。

#!/bin/shPATH=/opt/vc/bin:$PATHecho"CLOCK"for f in arm core h264
doprintf'%-8s: %sHz\n'$f$(vcgencmd measure_clock $f | cut -d= -f2 | numfmt --to=si)doneecho""echo"VOLTAGE"for f in core sdram_{c,i,p}doprintf'%-8s: %s\n'$f$(vcgencmd measure_volts $f | cut -d= -f2)doneecho""printf'%-8s: %s\n' temp $(vcgencmd measure_temp | cut -d= -f2)
$ watch ./hwinfo.sh
Every 2.0s: ./hwinfo.sh                                                                                              alarmpi: Mon Oct 31 21:59:04 2016

CLOCK
arm     : 1.3GHz
core    : 500MHz
h264    : 500MHz

VOLTAGE
core    : 1.3940V
sdram_c : 1.2000V
sdram_i : 1.2000V
sdram_p : 1.2250V

temp    : 72.0'C

measure_clockは色々な値が引っ張れるようだけど数字で呼び出すと何を指しているのかよくわからないのが欠点。

$ for f in {0..50}; do /opt/vc/bin/vcgencmd measure_clock $f; done | grep -v =0
frequency(1)=500000000
frequency(9)=163683000
frequency(22)=48000000
frequency(26)=4800000
frequency(28)=500000000
frequency(29)=74250000
frequency(42)=500000000
frequency(45)=1195000000
frequency(47)=249959000
frequency(50)=1920000

gpu_freqで設定すると core_freqとか h264_freqも全部変動するんだな。

mpv と youtube-dl 使って 60fps FullHD 動画再生するとヒートシンクつけてても85℃近くになって arm_freq がどんどん下がる…。やはりファンを付けるべきか。

mpv playerでYouTubeのミックスリストを再生する

$
0
0

YouTubeを観ている際によく出てくるこのYouTubeミックスリスト 曲やアーティストに基づく、ノンストップの再生リスト」

f:id:mattintosh4:20161105234040p:plain

これ以外にもユーザが任意に作成した YouTubeのプレイリストもある。これらは URL を持っているのだが、これを mpv に渡しても1曲目しか再生されない。

$ mpv 'https://www.youtube.com/watch?v=2OltRY1ccxs&list=RD2OltRY1ccxs'

youtube-dl がパースできる URL に問題があるのかわからないが、URL の watchplaylistに書き換えて現在再生している動画のパスを抜けばいいようだ。

https://www.youtube.com/watch?v=2OltRY1ccxs&list=RD2OltRY1ccxs
↓
https://www.youtube.com/playlist?list=RD2OltRY1ccxs
$ mpv 'https://www.youtube.com/playlist?list=RD2OltRY1ccxs'

Youtubeミックスリスト系には list=のあとに RDがつくみたいだが、これは無くてもよい。ブラウザ上で試してみると RDが付いているとプレイヤーの近くに再生リストが表示される仕組みらしい)

このプレイリストに対しても --shuffleオプションは有効。m3u ファイルに書いておけば複数のプレイリストを更に合成できる。


mpvで動画を再生すると出だしでコマ落ちが発生する問題

$
0
0

先日、Raspberry Pi 3 にファンを付けて温度上昇によるクロックダウンを予防することができたのだけど、動画を再生しようとすると開始からしばらくの間、遅延が発生する。

バッファサイズの調整してみたりしたが改善せず。

コンソールを見ているとキャッシュが溜まりきると改善することからキャッシュの方に原因がありそうだ。

ちなみに mpv にはキャッシュに関するオプションだけでもこれだけある。

$ mpv --list-options | grep cache
 --cache                          Choices: no auto yes (or an integer) (32 to 2147483647) (default: auto)
 --cache-backbuffer               Integer (0 to 2147483647) (default: 75000)
 --cache-default                  Choices: no (or an integer) (32 to 2147483647) (default: 75000)
 --cache-file                     String (default: ) [file]
 --cache-file-size                Integer (0 to 2147483647) (default: 1048576)
 --cache-initial                  Integer (0 to 2147483647) (default: 0)
 --cache-pause                    Flag (default: yes)
 --cache-secs                     Double (0 to any) (default: 10.000000)
 --cache-seek-min                 Integer (0 to 2147483647) (default: 500)
 --icc-cache-dir                  String (default: )

う〜ん、まさかなぁと思って --cache=noにしたら遅延しなくなった…orz

Raspberry Piの貧弱なストレージではキャッシュが逆に悪影響を及ぼすようだ。--cache-file=TMPとすることでキャッシュの場所を tmpfs にもできるけど Raspberry Piのメモリはそれほど高速でもないのでこれもダメだった。

Sambaサーバにしている Raspberry Pi 2 からデータを引っ張っているのでキャッシュは無くても別にいいか…。

~/.config/mpv/mpv.confでキャッシュを無効にするようにしておく。youtube-dl プラグインによる YouTubeの再生のときに遅延が発生するかもしれないが mpv の引数に --cache=autoを与えればこの設定は上書きできるのでそれほど手間にはならない。

cache=no

Raspberry Piに冷却用ファンを装備する

$
0
0

mpv で動画を再生していると 1280x720 60fps の動画がカクカクする。クロック不足かとも思ったがスムーズに再生できるタイミングもある。

オーバークロックしても効果がないので適当なモニタリング用シェルを作って watchで観察してみたのが前の記事。

mattintosh.hatenablog.com

どうも 1280x720 60fps の動画を再生していると、どんどん温度が上昇してデフォルトの上限温度である85度以上にならないようにクロックが落とされていた。ヒートシンクを付けた程度ではどうにもならない。

以前、Maker Faireで買った KSY さんのアルミケースサンプルにファンが付けられたなぁとネットを探してみると 5V の小型ファンというのはあまり種類が無いようで、しかも値段がアホみたいに高い。

のだが、秋月だけべらぼうに安い。5V 25mm 100円。

akizukidenshi.com

他にも同じ製品を取り扱っている店を見つけたがそれでも100円は無い。なんなんだこの値段は…。

とりあえずこれは買うとして、他にも違うサイズのものが欲しい。 これまた調べてみると東京ラジオデパートにファンを取り扱っているお店があった。 他の店では見たことが無いくらいたくさんの種類のファンが置かれていて、5V の種類も豊富。(30mm〜だったかも) 値段は400〜600円くらい。安い部類じゃないだろうか。とりあえず 30mm と 60mm を購入。

で、秋月の 25mm の方は固定方法がうまく思いつかなかったのでとりあえず 60mm を直載せしてみた。

2号機はとりあえずこんなんでいいや。これから温度コントロール用の回路組む

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

GPIO の 5V ピンから電源を直接接続。「こんなに風量必要ないよ!」っていうくらいよく回って冷える。

ただ、24時間回しっぱなしだと消費電量増えるしゴミも溜まるのでトランジスタを使ってコントロールすることにした。回転数を落とすためにベース抵抗をちょっと高めにしているので冷却具合はイマイチかもしれない。

60度を超えたら空冷開始するようにしてみた #RaspberryPi #RPi

Makoto Yoshidaさん(@mattintosh4)が投稿した動画 -

使ったトランジスタは定番中の定番、東芝の 2SC1815GR。既に製造が終了しているらしいが、秋月にはたくさんあった。

Raspberry Piを買ってからというもの、Linuxサーバとしてしか使ってなかったけど GPIO を使って電子工作というのもなかなかおもしろい。GPIO はシェルからも簡単に操作することができる。

数日後、また秋葉原をブラブラしていたら千石でファン付きのケースが売られていた。900円台だった気がする。 お店での見た目は結構ボロボロに見えるのだが保護フィルムが貼ってあるだけなので剥がせばとても綺麗。 ただちょっと組み立てが面倒かも。

しばらくこれで稼働してたんだけど、このファンがかなりうるさい。よく見たらサイズが 30mm だったのでこの前ラジオデパートで買ったファンと交換したら消費電力も下がってとても快適になった。(もともとケースについているファンが 0.19A で結構大食い) X-FAN 30mm のものに交換したんだけど長尾製作所のサイトを見ると受注生産品っぽい。

さて、1号機はケース交換したけど2号機がまだ残ってる。 また同じケースを買うのも面白みが無いので家にあったリーマーで穴をあけることにした。

リーマーでゴリゴリすること数分。 買ったはいいけどほとんど使ってなかったから穴が大きくなると正円にならないなんて知らなかった。質の問題? なんか微妙な八角形のようになったのでリューターでゴリゴリ…。(紙やすりがなかった…)

フェルトで磨いて出来上がり。ネジ穴は手に入りやすい 3mm。(右は未加工のもの)

Raspberry Piのケースに25mmファン用の穴を開けた #RaspberryPi #RPi

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

で、秋月のファンは M3 のネジで無理矢理固定しようとするとファンが歪むっぽいので M2.6 15mm のネジを西川さんで購入(ファンの厚みが 10mm、ケースの蓋が約 2mm)。プラネジにしようと思ったけどナットの方が品切れてたので見た目重視で六角穴付きネジ。なんかもうちょっと格好良い名前だった気が…。

Raspberry Pi case DIY. #raspberrypi #rs

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

ファンの底とヒートシンクとの距離が 5mm くらいになるのでちょうど良い位置。 こっちは検証用で使うときしか使わないのでとりあえず 5V 直結。秋月のファンもそれほどうるさくないし。 ファンのコネクタはいま QI コネクタを使っているけど、RS のケースは QI コネクタを使うと蓋が閉めづらくなるのでピンソケットの足にハンダ付けしてコネクタを作る予定。あぁ、QI コネクタにケース付けないで熱収縮チューブでもいいのか。

電子工作ネタはまた今度。

🍎 Nihonshu アップデート情報 2016年12月11日 🍷

$
0
0

前回の予告通り、冬コミの季節にバージョンアップです。

今回はリポジトリの更新だけで済んだので特に何も変更してません。

遂に Wine のバージョンも 2.x 台です。自分が使ってるのは 1.2 くらいだったような気がするけど長かったなぁ…。

そういえば Linux版も作るとか言ってたような気がするけど何もしてない…。

次は来年の夏コミの時期でしょうか。ではまた。

Raspberry Pi 3 で RCA 入力の液晶モニタに接続する

$
0
0

秋月電子で2,700円で売ってる RCAで接続するタイプの液晶モニタを買ってみた。

秋月で2700円で売ってるアナログディスプレイ買ってみた #raspberrypi #raspberrypi3 #rpi

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

年末の掃除もある程度終わって秋葉原に買い出し。

「クリスマスだしなんかもう一台 Raspberry Pi欲しいな〜」と思ったので RPi3 をもう一台購入した。これで3台目。マルツ行ったら23日から数量限定で特価販売していたらしい(3,980円だったかな?)。もう完売してたけど。

ふと、秋月店頭の平台を見ると小型の液晶モニタが売っていた。

akizukidenshi.com

家のラズパイ用のディスプレイは HDMIを2系統とも使いきってしまっているので遊びで買ってみることにした。

RCA接続となると当然 RCAプラグが必要になるんだけど、50円とかで売ってるプラスチックのやつは見た目が悪いのでトモカ電気さんでシャレオツなのを買ってきた。

Raspberry Piへの接続は Zero が確かヘッダピンで出来たはずだから 3 も同じかなと思ったら実は全然違って、ステレオミニプラグを使うようだった…。ていうかアレ4極対応してたのかよ…てっきりオーディオだけだと思ってた。

家に3.5mmの4極ステレオミニプラグの在庫がなかったのでとりあえず裏面のテストポイントを使って接続した。PP6 がビデオ、PP24が GND。

映りは値段相応だけど小型で良い #raspberrypi #raspberrypi3 #rpi

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

映りは値段相応だけど小型なところが良い。GPIO を使い潰さなくていいし。

Raspberry Piのアナログ出力は一般的なAV出力や iPodとも結線が違うらしいので自作するのは確定(ケーブル側からビデオ、GND、オーディオ、オーディオ。iPodとはオーディオのLRが逆)。オーディオは Bluetoothで接続するのでビデオだけでいいや。

早く Zero 欲しいなー。

Raspberry Pi 3 で RCA 入力の液晶モニタに接続する - ケーブル作成編

$
0
0

3.5mm 4極ステレオミニプラグが手に入ったのでケーブル作成。

Raspberry Pi専用アナログビデオケーブルでけた #raspberrypi #raspberrypi3 #rpi

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

単なるA/Vケーブルでも良かったんだけど、Raspberry Piの結線が特殊なことから買っても使えない可能性が高かった。ネット上の情報で Raspberry Pi 3 の結線がわかったので自作することにした。

ケーブルとRCAプラグはトモカ電気、3.5mm 4極ステレオミニプラグはオヤイデで入手。オヤイデに同じと思われるRCAプラグが売ってたけどトモカ電気より100円くらい高かった気がする。あと、トモカ電気さんは最初からビデオとオーディオそれぞれのゴムブーツを装着してくれていてバリエーションが多い。総製作費は650円くらいか。

ステレオミニプラグの結線はケーブル側から見てビデオ、GNDの順。オーディオは Bluetoothか PulseAudio でネットワークを経由させるので結線しなかった。

こんな感じで接続するケーブル作った #raspberrypi #raspberrypi3 #rpi #sdtv

Makoto Yoshidaさん(@mattintosh4)が投稿した写真 -

あとはスマホ用の三脚でも買ってくるか…。

Viewing all 878 articles
Browse latest View live