それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

WiFiが複数バンド(5/2.4GHz)で飛んでるときに、明示的に2.4GHz のssidに接続する

macWiFi接続で 2.4Ghz を強制してみた

CoreWLANで 同一SSIDで 2.4 / 5 GHz が飛んでいる場合に、2.4GHz に接続をしてみた。

人が多い時に、あきらかに5GHzが使われて、2GHz帯が空いてそうなので、一度接続してみたいなと思って。

接続しようにもMacが5GHzを使うので、選択できないなと。CoreWLANを読んでたら、明示的につなげそうだったので、繋いでみた。

//
//  main.m
//  WiFi-testing
//
//  Created by takuya on 20171130.
//  Copyright © 2017年 takuya. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreWLAN/CoreWLAN.h>
int main(int argc, const char * argv[]) {
  @autoreleasepool {

    CWWiFiClient *cw = [CWWiFiClient sharedWiFiClient];
    CWInterface *ci = cw.interface;
    NSSet *set = [ci scanForNetworksWithName:@"00_MCD-FREE-WIFI" error:NULL];

    // 2,4GHz is wlanChannel.channelBand == 1
    NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"wlanChannel.channelBand == 1 ",set];
    CWNetwork *target = [[set filteredSetUsingPredicate:pred2] anyObject];
    printf("\nThe target is %s\n", [target.bssid UTF8String]);
        for (CWNetwork *i in set) {
          printf("%25s %8s %s % 5ld % 5ld % 5ld % 5lddBm \n",
                 [i.ssid UTF8String],
                 //2=>5Ghz 1=>2.4Ghz
                 ((i.wlanChannel.channelBand==kCWChannelBand5GHz)? "5GHz" : "2.4GHz"),
                 [i.bssid UTF8String],
                 i.rssiValue,
                 i.wlanChannel.channelWidth,
                 i.wlanChannel.channelNumber,
                 i.noiseMeasurement
                 );
        }


    [ci disassociate];
    [ci setPower:YES error:NULL];
    [ci disassociate];
    [ci setWLANChannel:target.wlanChannel error:NULL]; //チャンネルのデフォルトを2.4GHzにする
    [ci associateToNetwork:target password:NULL error:NULL];

  }
  return 0;
}

一応つながる

f:id:takuya_1st:20171208180446p:plain

しかし、すぐに5Ghzにされる。

しかし、接続中に、Macに2.4GHz → 5GHz にされてしまう。

同一SSIDで5GHzが飛んでたらそっちへつなぎ替えるプロセスが居るらしい。どれだ。。。

なんな、launchd から起動されているDAEMONを止めないとダメっぽいぞ。

Javaで音を鳴らす

Java でサウンド再生

サウンド再生すればちょっと楽しいかなって思ってやってみた。

準備

WAV ファイルを作る

ffmpeg input.m4a output.wav

いまどきWAVファイルなんて扱ってる人は少ないだろうからメモしておく

Java でWAVファイルを使って音を鳴らす。

AudioStream を使えばぱぱっと出来る。

import java.io.*;
import sun.audio.*;


public class PlaySound{

  public static void main( String[] args)  throws Exception {
    
    String f_name = "/Users/takuya/sample.wav";
    System.out.println("Hello World.");

    InputStream in = new FileInputStream(f_name);
    AudioStream as = new AudioStream(in);

    AudioPlayer.player.start(as);

  
  }

}

これでも結構かんたんに音がなる。

コレもサンプルコードで見つけた。でもちょっとコードが古い。

import java.io.*;
import sun.audio.*;

import javax.sound.sampled.*;

public class PlaySound{

  public static void main( String[] args)  throws Exception {
    
    String f_name = "/Users/takuya/sample.wav";
    System.out.printf("playing %s \n", f_name);

    File f = new File( f_name );
    AudioInputStream ais = AudioSystem.getAudioInputStream(f);

    AudioFormat  af = ais.getFormat();
    DataLine.Info info = new DataLine.Info( SourceDataLine.class, af , AudioSystem.NOT_SPECIFIED  );

    SourceDataLine line = (SourceDataLine) AudioSystem.getLine( info  );

    line.open( af , AudioSystem.NOT_SPECIFIED );
    line.start();
    int buff_size = 1024*3;
    int bytes_read = 0 ; 
    byte[] data = new byte[buff_size];

    while ( bytes_read != -1 ){
      bytes_read = ais.read( data, 0, data.length  );
      if ( bytes_read > 0 ) {
        line.write(data, 0, bytes_read);
      }
    }

    line.drain();
    line.close();
  }

}

参考資料

ドコから持ってきたのか忘れた。

ubuntu のネットワーク設定が変わってる /etc/network/interfaces no longer used

ubuntu 17 入れたらネットワーク設定でつまづいた。

VirtualBoxでネットワーク・カードを追加したり消したりしたかったのに、DHCPからIPが振ってこない。 DHCPが有効じゃないのかとか、VBOXの設定を間違えたかとアレコレ時間を浪費したのでメモです。

DHCPからIPが取れない。

DHCPは有効になってるのに、IPアドレスが取れない ip link set DEV up も試したけどダメだった。

/etc/network/interface を書き換えても無駄だった。→使われない

ネットワークが systemd 管理下に置かれてる。systemd-networkd.service というサービスが制御をしていた。

検索結果を調べたらNetworkManagerが多いのですが、たしかに入ってる場合もあるとは思いますが、 ubuntu Server版 なので特に無いので、systemdの設定を直接する必要があった。

ググってみた結果。/etc/network/interfaces no longer used という恐ろしい文言を見かけた。

状態の確認

起動しているとか、有効になってるかどうかはまずはステータスを見れば解る。

systemctl status systemd-networkd

設定

設定は、/etc/systemd/network 次の場所に任意のファイル名にして書く。

設定例 /etc/systemd/network/25-enp0s8.network

[Match]
Name=enp2s0

[Network]
DHCP=ipv4

match も強引なマッチが書ける

[Match]
Name=enp*

[Network]
DHCP=ipv4

スタティックに静的IPを割り振るには

[Match]
Name=enp0s8

[Network]
DNS=8.8.8.8
Address=192.168.1.87/24
Gateway=192.168.1.254

DNSなどもここで指定する。

/etc/network/interace は何処へ・・・

Archなどもおなじなのですが。

ファイルを作成するのはアレコレ調べたら、やっぱりもう使われてない。systemd に入ってから、こんな所変えてどうするんだよ。。。

The package ifupdown and so /etc/network/interfaces are no longer used. Ubuntu 17.10 Server uses the package netplan instead, which configures systemd-networkd.

ああ、つらい。

ネットワークまわりを変えられるとトラブル多いよな

どうして変えちゃったの。 てか変えるなら /etc/neworking/interfaces のファイルに注意と書いといてよ。。。

/etc/resolv.conf お前もか

この変化で、DNSに関しても動かなくなってる。

唯一の救いは、ディストリ毎の差異が減ることかな

CentOSDebian系でネットワークの設定方法が異なったり、書式が異なったりすることに依る混乱には遭遇しないのは良いことかもしれない。

参考資料

0001docomo に複垢でつながらないのをCoreWLANで解決した話

0001docomo につながらない詰み状況を回避する

0001docomo は1アカウント(契約)につき、コネクションを1接続に限定される。

そこで、複数台を接続するには、家族や友人の使ってないWiFiアカウントを強奪したり、もう1つ契約すれば良いのですが。

複垢使い分けできないことがある。

iOS / Mac だと複垢を使い分けできない。

iPhone / iPad / Mac / iPad Pro と複数台でkeychains を共有していると 1台だけが0001docomoのWiFiに接続が可能になる。

もし複数契約を持っていた場合に、iPhone / iPad / Mac / iPad Proで利用するdocomoアカウントを切り分けようとしても、keychainsで共有されているために、使い分けができない。

キーチェーン同期・・・

どれか1台で接続設定をしてしまうと、残りの機器にKeychainsで同期されてしまう。 そして複数アカウントを設定してもすべてが同じKeychainsになってしまう。 結果として、複数アカウントを契約したとしてもキーチェーン共有の問題でアカウントの使い分けが出来なかった。この問題にもう3年以上苦しんでいた。

networksetup コマンドでも無理

networksetup コマンドには、802.1 の Enterprisze がない. 0001docomoは 802.1Xなのでこのコマンドではお手上げだった。

takuya@Desktop$ networksetup -a | grep 8021
103:networksetup -import8021xProfiles <service name> <file path>
104:networksetup -export8021xProfiles <service name> <file path> <yes no>
105:networksetup -export8021xUserProfiles <file path> <yes no>
106:networksetup -export8021xLoginProfiles <service name> <file path> <yes no>
107:networksetup -export8021xSystemProfile <service name> <file path> <yes no>
takuya@Desktop$ networksetup -a | grep Enter
takuya@Desktop$ networksetup -a | grep airport
53:networksetup -getairportnetwork <device name>
54:networksetup -setairportnetwork <device name> <network> [password]
55:networksetup -getairportpower <device name>
56:networksetup -setairportpower <device name> <on off>
takuya@Desktop$

CoreWLAN フレームワーク

ある日ふと思い立って、MacObjective-C で CoreWLANのAPIでなんとかなるんじゃないか。 networksetup コマンドでもお手上げだったので、802.1x のEnterprise認証を指定するAPIがあるんじゃないか

一縷の望みを託してAPIを読んでみたら、無事接続できたのでメモを残します。

コマンドを作って実行してみたら、Macからは無事に指定のEnterpriseユーザー情報で接続できた これで、無事にMaciPhoneで別のアカウントを使って同時に0001docomoを使えるようになった。

しんどい接続についても結構かんたんに解決したし、WiFiがナゼかつながらないっていう問題もなかった。

このコマンドにEnterpriseのパスワードを直書きしているが、まぁそこま置いていて。

サンプルコード

//
//  main.m
//  WiFi-testing
//
//  Created by takuya on 20171130.
//  Copyright © 2017年 takuya. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreWLAN/CoreWLAN.h>
int main(int argc, const char * argv[]) {
  @autoreleasepool {

    CWWiFiClient *cw = [CWWiFiClient sharedWiFiClient];
    CWInterface *ci = cw.interface;

    [ci setPower:YES error:NULL];
    [ci disassociate];

    NSSet *set = [ci scanForNetworksWithName:@"0001docomo" error:NULL];

    CWNetwork *target;
    for (CWNetwork *i in set) {
      long l = i.rssiValue;
      NSLog(@"rssi=%ld", l);
      if ( i.rssiValue < target.rssiValue ){
        target = i;
      }
    }
    NSLog(@"%@", target);
    if ( target == NULL ){
        NSLog(@"SSID not found.");
        return 1 ;
    }
    NSError *err;
    BOOL ret = [ci associateToEnterpriseNetwork:target
                                       identity:NULL
                                       username:@"xxxxx-spmode@docomo"
                                       password:@"xxxx" error: &err];

    NSLog(@"%s", (ret? "YES":"NO"));
    if ( ! ret ){
      NSLog(@"%@", err);
      return 1 ;
    }
   return 0;

}

参考資料

https://developer.apple.com/documentation/corewlan

ツイキャス(twitcasting)のm3u8 を取り出して遊ぶ

ツイキャスのm3u8 のURLを見つけた

m3u8 に調べていたら、ツイキャスもhls のm3u8 で配信されていることがわかった。

フォーマット

http://twitcasting.tv/$twicas_username/metastream.m3u8

コレだけで再生出来るっぽいぞ。

もしかして Raspi で再生できる??

omxplayer --sid 2 http://twitcasting.tv/$twicas_username/metastream.m3u8

オモシロイね

twicas を取得してみた結果。

解像度や音だけのストリームもあるので、ミキシングして楽しめそう。

Input #0, hls,applehttp, from 'http://twitcasting.tv/XXXX/metastream.m3u8':
  Duration: N/A, start: 1355.776000, bitrate: N/A
  Program 0
    Metadata:
      variant_bitrate : 220000
    Stream #0:0: Video: h264 ([27][0][0][0] / 0x001B), none, 90k tbr, 90k tbn, 180k tbc
    Metadata:
      variant_bitrate : 220000
    Stream #0:1: Audio: aac ([15][0][0][0] / 0x000F), 0 channels, fltp
    Metadata:
      variant_bitrate : 220000
  Program 1
    Metadata:
      variant_bitrate : 88000
    Stream #0:2: Video: h264 ([27][0][0][0] / 0x001B), none, 90k tbr, 90k tbn, 180k tbc
    Metadata:
      variant_bitrate : 88000
    Stream #0:3: Audio: aac ([15][0][0][0] / 0x000F), 0 channels, fltp
    Metadata:
      variant_bitrate : 88000
  Program 2
    Metadata:
      variant_bitrate : 64000
    Stream #0:4: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, mono, fltp
    Metadata:
      variant_bitrate : 64000

参考資料

gist.github.com

radikoのjs / m3u8 / hls 化に併せてAuthtokenと再生URL取得をするサンプル

authtokenの取得方法が変更になってた

Radikoが、JSプレーヤーでHTML5になっていたので、ちょっとリクエストを追いかけて見てた続き

  • auth1 へリクエスト投げてauth_token を取得
  • auth2 でauth_token を有効化
  • m3u8にリクエストを投げる
  • 使い切りのchunklist の url が投げられるのでそこへリクエストを出す。

だいたいはコレで再生ができると思う。

python pip とか npm にしてやろうって人も居るだろうけど、radikoは年に1回にAPI変更することがあるので、メンテする覚悟がないとゴミをnpm に作ることになるよね。

コード書いた

gist.github.com

現在フォルダのファイルシステムのフォーマットを調べる(ext4 か btrfs かなど)

あれ?ファイルシステムがわからない。

このディレクトリが入ってるHDDのファイルシステムってなに?btrfs ? XFS ?それとも ext??

ファイルシステムのフォーマットのタイプを調べる方法が必要なので調べました。

df で調べることが出来る。

takuya@raspi3:/var/samba$ df -Th .
ファイルシス   タイプ サイズ  使用  残り 使用% マウント位置
/dev/sda       btrfs     58G   32G   25G   57% /var/samba

ちなみに、mac でできるよ。

brew で入れた df を使えば同じことが出来る

takuya@Desktop $ df -Th .
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/disk1     hfs   233G  199G   35G  86% /

おお! hfs って表示された。

ext4 の例

takuya@$ ssh mine 'df -Th ~'
Filesystem            Type  Size  Used Avail Use% Mounted on
/dev/mapper/home ext4   50G   26G   21G  56% /home

その他の選択肢なども

今回は、今いるディレクトリから調べたいってことなので、df を使いました。

ディスクが解るなら、lsblk や fsck を見ると良いかも

  • lsblk -f
  • fsck -N /dev/sda
  • blkid /dev/sda

参考資料

https://www.tecmint.com/find-linux-filesystem-type/

swap ファイルをswapon するとエラーになる。(btrfs)

2022/05/23 追記

Linuxカーネル 5.x から btrfs 内部にスワップファイル設置がサポートされてます。新しい方に書き直した。

新しい方法 → btrfs 内部にスワップ・ファイルを設置する - それマグで!

swap ファイルが作れない

takuya@raspi3:/var/samba$ sudo swapon out.swp
swapon: /var/samba/out.swp: swapon failed: 無効な引数です
takuya@raspi3:/var/samba$ LANG=c sudo swapon out.swp
swapon: /var/samba/out.swp: swapon failed: Invalid argument

btrfsにはswapが作れない

エラーメッセージがinvalidとしかでないのでわからなくなる

散々、検索して理由を探したけど見当たらなくて。すごく青ざめてパニックになってた。わかってしまうとなんだって感じ。

ext4 の中には swap file が作れるが
btrfs の中には swap file が作れない。

単純にswapon でマウントしようとしただけではinvaid エラーになって気づきにくい。っていうかしらないとハマる。

慌てて確認したら、btrfs ですね。。。

takuya@raspi3:/var/samba$ df -Th .
ファイルシス   タイプ サイズ  使用  残り 使用% マウント位置
/dev/sda       btrfs     58G   32G   25G   57% /var/samba

スワップファイルが作れない解決法

btrfs 上に直接作れないだけで。作成済みのファイルをloopback で接続すれば出来る。

dd if=/dev/zero of=swap.img count=512 size=1M
losetup swap.img /dev/loop1
swapon /dev/loop1

btrfs がinodeを管理しちゃったり場所を移すので出来ないんだと思う。まぁ不便だね

参考資料

https://www.linux.com/forums/lfs201-class-forum/lab-131-swapon-failed-invalid-argument

動画の再生時間を取得する。json にする。

動画の再生時間(何分の動画か調べる)

ffprobe を使うと瞬殺

もし忘れた場合、再生時間っていう表現が曖昧で検索しにくいの苦労しそうなのでメモ。

 ffprobe  -i input.mp4 -show_entries format=duration

サンプル

takuya@Desktop$ ffprobe  -i input.mp4 -show_entries format=duration -print_format json  -loglevel quiet  | jq .
{
  "format": {
    "duration": "302.736000"
  }
}

ターミナルで改行とEnterで表示がおかしく異常になった時のなおし方

ターミナルで改行や表示がおかしくなった時

たまにありますよね 。\r \n  の改行がおかしくなって、エンターキーで改行しても反映されない時って。

こんな感じに、表示で改行と幅がおかしくなってしまうよね。

takuya@:~$takuya@:~$takuya@:~$
              takuya@:~$
                     takuya@:~$

入力した文字が表示されない return入力で改行されない

などなど、Ctrl-C(INT) やKILLで強制終了した時などによく起きますよね

このように、Terminalの入力が異常になったときの直し方

reset コマンドを使う

reset

という便利なコマンドがあります。

使ってみたサンプル

takuya@:~$takuya@:~$takuya@:~$takuya@:~$takuya@:~$
reset
takuya@:~$
takuya@:~$
takuya@:~$ type reset
reset は /usr/bin/reset です

その他の解決方法

stty echo

参考資料

https://superuser.com/questions/983755/os-x-terminal-behaves-oddly-after-running-python-interactively

Raspiのomxplayer でRadikoのm3u8 を再生する(omxplayer でHTTPカスタムヘッダ追加)

何気なく、omxplayer のヘルプを読んでたら --avdict という項目を見つけたので調べてみた。

omxplayer

        --avdict 'opts'         Options passed to demuxer, e.g., 'rtsp_transport:tcp,...'

コレを使えば、カスタムヘッダを追加できるんじゃないかなと。 つまり、Raidkoの再生にffmpeg が要らなくなるじゃん?

omxplayer --avdict '  'X-MY-HEADER: my_header_key'

この形でカスタムヘッダを追加できる。 ffmpeg の --header 相当ですね。

ってことでやってみた

再生する手順

最初に、AuthTokeを持ってm3u8 にアクセスして、テンパラリのURLを生成してもらう。次にそのURLへリクエストを放り込む m3u8 内に記述されたm3u8 のネストをomxplayer は取得できないので、いったんcurl を経由する必要がある。

m3u8のURLを出してもらう

takuya@raspi3:~/omxplayer$ curl -H  'X-Radiko-AuthToken: xxxxxxxxxxxxxxxxxxx' 'https://radiko.jp/v2/api/ts/playlist.m3u8?station_id=MBS&ft=201711101530&to=201711101730'
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=52973,CODECS="mp4a.40.5"
https://radiko.jp/v2/api/ts/chunklist/8NwMph0V.m3u8

m3u8 のURLにomxplayer でアクセスする。

takuya@raspi3:~/omxplayer$ omxplayer -hw -o local --avdict 'X-Radiko-AuthToken: xxxxxxxxxxxxxxx' https://radiko.jp/v2/api/ts/chunklist/8NwMph0V.m3u8
Audio codec aac channels 2 samplerate 48000 bitspersample 16
Subtitle count: 0, state: off, index: 1, delay: 0
have a nice day ;)

これで再生できた。raspi 使う限りにおいてffmpeg でパイプする必要もなくなるしomxplayer だけで解決するのも嬉しい。

東京の放送が聞きたきゃmoperaやLTE経由すればいいし、大阪や関西の放送が聞きたければさくらVPSを経由すればいいし。既存のインフラでなんとかなるのが嬉しい。ちなみにYahooBBだとほとんど福岡にされるのはナゼなんだろう。便利だけどw

Raspberry Pi 3は優秀なRadikoプレーヤーになりそうです。

ただ、m3u8 の場合は スキップが効かないのでそのへんは今後の課題ですね。。。

bashスクリプトファイルの実行者が、実行ユーザがroot(id:1)か調べる

root じゃなきゃ、終了するとかしたい

シェルスクリプトの実行ユーザを調べて、root 以外が起動したら処理をしない。などと簡単に書きたい時。

whoami を if 文に突っ込むだけでいい

if [[ $(whoami) == 'root' ]] ; then
  echo user root
else
  echo user is not root
fi

sudo 経由で起動してなければexitするとかに使える。

その他の選択肢

環境変数をチェックするのもかんたんなチェックの代替案として良いかもしれない。

  • $UID のチェック
  • $USERのチェック

厳密なチェックにはならないけど。環境変数だしね

export USER=aaa
echo $USER #aaa ← あっ

vimで行末に一括で追加(箱形・矩形の選択で行末に一括追加)

行末にまとめて追加したいとき

vim には色々とやり方があるんだよね。僕は迷わず選択範囲を作って正規表現で置換してた。

箱形選択で出来たら便利だよなぁとAtomを使ってる人を見ながら思った

Vim で箱形選択の行末(末尾:文末)に一気に文字を追加

  1. 選択で箱形範囲作って( ctrl -v
  2. 行末まで選択 ( $
  3. Appendで ( shift-a / A
  4. 文字を追加 ( ;;;;

ポイントは、Visual Blockの選択範囲を作成後に$(行末)で行末まで選択肢、追記でモード切替するところ。

箱型選択は忘れないが、行末まで選択は忘れそうになるので、メモを残すことにする。

サンプル

https://i.gyazo.com/9f72b83ac8aa7a200a9411dd1ea81d86.gif

ポイント

ポイントは、箱型で行末まで選択して、追加すること

2021-01-14

google 検索でこのエントリが無視されるのでキーワードを追加。

mac で WiFi の接続情報を取得する

macWifiの現在のIPを取得したい

$ networksetup -getinfo Wi-Fi

実行サンプル

takuya@$ networksetup -getinfo Wi-Fi
DHCP Configuration
IP address: 100.119.116.5
Subnet mask: 255.255.255.0
Router: 100.119.116.252
Client ID:
IPv6: Automatic
IPv6 IP address: none
IPv6 Router: none
Wi-Fi ID: 60:xx:xx:a1:82:xx

システム環境設定のネットワークで見られる情報と同じものを取得するには networksetup コマンドを使うと楽ですね。

IP アドレスやゲートウェイのアドレスなどを取り出す。

ここから値を取り出すには次のようにすると楽かも

takuya@$ networksetup -getinfo Wi-Fi | \grep -oP '(?<=Router: )\d\d\d.\d\d\d.\d\d\d.\d\d\d'
100.119.116.252

正規表現は適当なのであんまり参考にならないけど

grep の後読み条件で取り出せば確実に取り出せて嬉しい。

関連資料

grepで先読み後読みを使うには - それマグで!