Title

ffmpegで字幕付きMKVファイルをmp4とかになんとかする

字幕付きMKVファイルをmp4に変換したい場合、画面内に埋め込んでしまうのが確実です。
まずffprobeで埋め込みたい字幕がどこに入っているか確認します。

0:0がビデオ
0:1が音声(PCM)
0:2が音声(DTS5.1ch)
0:3が字幕(日本語)
とわかったので

こんな感じでやると埋め込めるみたいです。

Windowsで謎のproxy設定が残っている

設定画面でproxyをオフにしているのに、なぜかproxy経由でつなごうとしてしまう問題。

netsh winhttp show proxy

で確認。

netsh winhttp reset proxy

変なのが残っていたらでリセット(削除)

RARファイルをZipファイルに一括変換する方法

7-Zipはzipもrarも扱えるので、7-Zipを利用して以下のようなBATファイルを用意すると便利です。

変換BATファイルのダウンロードはこちらからどうぞ→https://www.ryusuke.net/public/RARtoZIP.zip

このBATファイルにRARファイル(複数可)をDrag&DropするとRARファイルがZipファイルに変換されます。

@echo off

rem ▼7zをインストーラーを使わず配置している場合は以下にパスを記載
set PATH7Z="C:\Program Files\7-Zip\"

if exist %PATH7Z% goto convert

for /F "TOKENS=1,2,*" %%I IN ('REG QUERY "HKEY_CURRENT_USER\SOFTWARE\7-Zip" /v "Path"') DO IF "%%I"=="Path" SET PATH7Z=%%K

:convert
set path=%path%;%PATH7Z%

for %%i in (%*) do (
	7z e -spf -o"%%~dpni" %%i
	7z a "%%~dpni.zip" "%%~dpni\*"
	rmdir /s /q "%%~dpni"
)
echo end
pause

バッチファイルの内容

7-Zipは通常”C:\Program Files\7-Zip\”にインストールされますので、ファイルの存在を確認しています。

もしみつからない場合は、レジストリからインストールパスを取得します。どちらも該当しない場合はパスを修正してください。

for文の中では、一旦RARファイルを展開し、Zipに圧縮したのち、その後展開したフォルダを削除しています。

Adobeのインストーラーが動かない(エラー206)

どうやってもネットワークにつながらないといわれる問題。

どうやらproxyを設定が残っているとPxory経由でアクセスしようとして失敗しているような・・・?

コマンドラインでnetshを起動 → winhttp と打つ

show proxyで確認。

もし設定があるようだったら

reset proxy

で消去。

iOSデバイス解像度一覧

2018/10月に発表された新iPad Proに対応した解像度一覧です。
物理解像度ではなく、開発に必要なポイント(座標)基準です。
今回追加された新しい解像度はiPad Pro11インチです。

320 375 414 768 834 1024
480 iPhone3GS以前
iPhone4,4S
568 iPhone 5,5s,5c
iPhone SE
667 iPhone 6,6s,7,8
736 iPhone 6/6s,7,8 Plus
812 iPhone X
iPhone XS
896 iPhone XR
iPhone XS Max
1024 iPad 1,2
iPad 3,4
iPad Air
iPad Air 2
iPad Pro 9.7
iPad Mini
iPad Mini 2,3,4
1112 iPad Pro 10.5
1194 iPad Pro 11
1366 iPad Pro 12.9

青字はx3解像度、黒色はx2解像度、グレーは非Retinaです。

いろんなサイズのテスト画像をたくさん作るには

アプリのUIなんか作っていると、要所要所でPNG画像が必要になるのですが、ひとまずテスト画像で進めたいことはよくありますよね。
まったくないと試せないので。

少量ならPhotoshopとかで適当に作れば良いのですが、量が多いと面倒です。
コマンドラインでサイズ指定したら画像ができるみたいなことはやれば出来ると思うんですが、とっさにいつも無いので作りました。

同じもの作るの3回目くらいなんですが、いつもどこかいってしまってファイル名すら思い出せないので今回はここに貼っておきます。

createTestImage.zip(WIN32)

引数にファイル名 横サイズ 縦サイズ を入れるとランダムな色の背景の画像にファイル名が入った画像ファイルが生成されます。
ファイル名にスペースとか入れられないですので、諦めるかソースコード修正してください。

>createTestImage.exe createTestImage.png 200 100

↓こういう画像ができます。

ソースコード

#include <Windows.h>
#include <gdiplus.h>
#include <string>
#include <time.h>  
#include <stdio.h>
#include <tchar.h>

#pragma comment(lib,"Gdiplus.lib")

using namespace Gdiplus;

#include <cstdlib>
using namespace std;
ULONG_PTR           gdiToken;
GdiplusStartupInput gdiSI;

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
	UINT  num = 0;
	UINT  size = 0;
	Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
	Gdiplus::GetImageEncodersSize(&num, &size);
	if (size == 0) return -1;

	pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
	if (pImageCodecInfo == NULL) return -1;
	GetImageEncoders(num, size, pImageCodecInfo);
	for (UINT j = 0; j < num; ++j)
	{
		if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
		{
			*pClsid = pImageCodecInfo[j].Clsid;
			free(pImageCodecInfo);
			return j;
		}
	}

	free(pImageCodecInfo);
	return -1;
}

void createImage(WCHAR *filename,int width,int height)
{
	Bitmap *outputImage = new Bitmap(width, height, PixelFormat32bppARGB);

	Gdiplus::Graphics graphics(outputImage);
	graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);

	Pen pen(Color(255, 0, 0, 0), 2);
	int r = (int)((double)rand() / (RAND_MAX + 1) * (128) + 127);
	int g = (int)((double)rand() / (RAND_MAX + 1) * (128) + 127);
	int b = (int)((double)rand() / (RAND_MAX + 1) * (128) + 127);

	graphics.Clear(Color(255, r, g, b));
	graphics.DrawRectangle(&pen, 0, 0, width-1, height-1);

	TCHAR sizeText[100];
	wsprintf(sizeText, L"%dx%d", width, height);

	Font fontMain(L"Arial", 14);
	Font fontSize(L"Arial", 9);
	StringFormat format;
	format.SetAlignment(StringAlignmentCenter);
	Gdiplus::SolidBrush blackBrush(Color(255, 0, 0, 0));

	graphics.DrawString(filename, -1, &fontMain, RectF(0.0f, 3.0f, width - 1.0f, height - 1.0f), &format, &blackBrush);
	graphics.DrawString(sizeText, -1, &fontSize, RectF(0.0f, 28.0f, width - 1.0f, height - 1.0f), &format, &blackBrush);


	CLSID id;
	GetEncoderClsid(L"image/png", &id);
	outputImage->Save(filename, &id);

	delete outputImage;

}
int _tmain(int argc, _TCHAR* argv[])
{
	if (argc <= 3)
	{
		printf("createTestImage Size Filename\n\n");

		printf("for example:\n\ncreateTestImage.exe testimage.png 128 256\n\n\n");
		return 0;
	}


	srand((unsigned)time(NULL));
	GdiplusStartup(&gdiToken, &gdiSI, NULL);

	createImage(argv[1], _wtoi(argv[2]), _wtoi(argv[3]));

	Gdiplus::GdiplusShutdown(gdiToken);
	return 0;
}

ご覧頂けるとおり、エラー処理入ってません!

iOS発売年ごとの最終対応OSバージョン(2016年版)

以前作成した、デバイスごとにサポートするiOSの最終バージョンを一覧を更新しました。

・iOS5以前をサポートすることは、現在困難だと思います。
・iPhone3GSとiPod touch代4世代をサポートしなくて良ければiOS6のサポートをやめられます。
 実質もうOKかと思います。
・iPhone4をサポートしなくてよければiOS7のサポートをやめられます。
・iOS8を最終バージョンとする端末はありませんが、iOS8のiPadはまだ多数あるようなので対応しておいたほうがいいかも。

[3.1.3まで]
(2007)iPhone
(2007)iPod touch 1gen

[4.2.1まで]
(2008)iPhone3G
(2008)iPod touch 2gen

[5.1.1まで]
(2009)iPod touch 3gen
(2010)iPad 1gen

[6.xまで]
(2009)iPhone3GS
(2010)iPod touch 4gen

[7.xまで]
(2010)iPhone4

[8.xまで]
該当なし

[9.xまで]
(2011)iPhone4S
(2012)iPod touch 5gen

(2011)iPad2
(2012)iPad mini
(2012)iPad 3gen

[10対応(最終バージョン未定)]

(2012)iPhone5
(2013)iPhone5C/S
(2013)iPad mini2
(2014)iPhone6/6 Plus
(2015)iPhone6S/6S Plus
(2016)iPhoneSE Plus
(2016)iPhone7/7 Plus

(2015)iPod touch 6gen

(2012)iPad 4gen
(2013)iPad Air
(2014)iPad Air2
(2015)iPad Pro
(2016)iPad Pro(9.7インチ)

(2014)iPad mini3
(2015)iPad mini4

QRコードの誤り訂正レベルの判別方法~アイカツスターズ!のQRコードを分析してみる

(分析ってほどのことはしませんが、既に生成済みのQRコードの誤り訂正レベルはどれなんだろう? って思った時に調べる方法についての記事が意外となかったので)

バンダイにものすごい売上をもたらしたアイカツ!~アイドルカツドウ~ がアニメも終わって、ゲームも稼働終了となり、アイカツスターズ!という新しい展開にするそうです。
アイカツカードといえば裏面のバーコードを読み取る形式だったので、ものすごい種類(2500種類くらい?)を捌ききれるのかと検証してみましたが、全然余裕でしたというのがその時の結論。

ちょうどプロモーションカードを配布していたので、娘のために貰ってきました。

このカードはプロモーション用なので普通の印刷ですが、筐体から排出されるカードはオンデマンド印刷に変わります。
というわけで、裏面にあったバーコードが表面のQRコードに変わりました。
実は今主流の形式ですね。

というか、「妖怪ウォッチともだちウキウキペディア」が既に同じ形式なので新しくもなんともありません。

こうやって写真撮ってしまうと、QRコードも利用できてしまうのが困る。
以前はカードしか挿入できなかったので、一旦紙に印刷しないとスキャンできませんでしたが、今回は筐体のCMOSカメラに見せる形式のようなので写真撮影→スマホ画面でも認識するでしょう。
なので、一応QRコードをボカしました。

前回同様、どのくらいのコードが入っているのか見てみますかね・・・。
別にセル数変えられるからいくらでも拡張できちゃうんだろうけど。

まず、QRコードリーダーで読み込んでみると、「http://dcd.sc/」で始まるURL形式で84文字のデータになっています。カードの固有情報と思われる部分はそのうち65バイトかな?
URLには記号も含まれているのでQRコード的にはバイナリ扱いになります。

セルのサイズから、バージョンは8です。
あと、QRコードには誤り訂正レベルというのが4種類(L,M,Q,H)があり、Hが最も復元しやすく、Lが最もデータ量が多くなります。

誤り訂正レベルは何使ってるんですかね。(84byteは一番誤り生成レベルが高いHでちょうど入るのでおそらくHなんでしょうけど、一応確認します)

下の画像は、上のカードのQRコードの左上を拡大したものです。

赤枠の部分は、タイミングパターンというもので、必ず白と黒の交互のパターンになっています。
他の部分のセルを切り出すときのヒントになるマーカーみたいなものですね。

青枠の部分が形式情報を保存している部分です。
15bitあります。なお、この位置以外にも、右上と左下の検出シンボルにも分割して同じ情報が入っています。(汚れや隠れに対応するためと思います)

この0~14の部分を、白を0,黒を1として読み取ると、
001110011100111
になります。(この数字の左端が上位ビットなので=画像の14の位置です)

この15bitのうち、最初の2bitが誤り訂正レベルを示しています。
ただし、同じビットが続くと読み取り精度に悪影響を与えるため、101010000010010でXORをとってあります。
といわけで、もう一度XORをかけて元に戻すと、
100100011110101
になります。

最初の2bitは10ですね。
誤り訂正レベルは以下のように定義されていますので、このコードの誤り訂正レベルはHということになります。

誤り訂正レベル一覧:
L 01
M 00
Q 11
H 10

もう少し、実用的にまとめると、上の画像の14と13の部分を見て、
□□(白,白)だったら、誤り訂正レベルH
□■(白,黒)だったら、誤り訂正レベルQ
■□(黒,白)だったら、誤り訂正レベルM
■■(黒,黒)だったら、誤り訂正レベルL
です。

というわけですので、セルサイズが変わらないという前提で言えば、コーデ(衣装)カードは84byteのURL形式が固有IDとして割当られるようです。

旧アイカツカードにも実はQRコードも併記されているんですが、こちらはもっとコード量が少ないです。
更にURLが「http://aikatsu.com/」になっているので、固有コードはもっと短いです。

旧アイカツカードの裏のQRコードの誤り訂正レベルはL(7%復元)、バージョン4だったのに対して、アイカツスターズのQRコードは最も誤り訂正レベルの高いレベルH(30%復元)、バージョンは8になっていますね。オンデマンド印刷での品質を考慮した結果でしょうか。

ところで、Webにある、QRコード生成サイトで、同じURLのQRコードを同じバージョンと誤り訂正レベルで作ってみても、QRコードが同じになりません。
同じになる場合もあるんですが、QRコード生成時に、いまいち規格上固定されない部分や、規格の年式による微妙な違いがあり、実装により変わるみたいです。

アイカツスターズの筐体が、この部分の違いまで見極めて勝手に作ったQRコードを不正なカードと判断するかするかどうかは・・・まぁ、しないでしょうね。

なお、ライバル機である、プリパラのQRコードは白黒反転されております。
これはデータの保護というよりは、デザイン面での配慮な気がします。

(つづき)Y!mobileはHTTPのプロトコルを監視して帯域制限を行っている

前回の記事のつづきです。

月が変わり、帯域制限の対象ではなくなったはずなのでもう一度測定してみました。
(1MBのファイルを転送)

ファイルタイプ 転送時間 速度
.zip 1.2秒 849KB/s
.bin 0.9秒 1.10MB/s
.exe 1.1秒 966KB/s
.lzh 1.2秒 864KB/s
.pdf 1.2秒 869KB/s
.aikatsu 1.2秒 864KB/s

あ、速い・・・。

帯域制限がかかっていたファイルタイプと、そうでないファイルの速度差がなくなりました。
月末に測定した時の転送時間は、zipファイルは80秒弱、pdfファイルは2秒ちょっとでした。
上記表以外にも複数回測定してみましたが、概ね安定した速度です。

また、帯域制限がかかっていないと思っていたファイルでも転送速度がだいぶ速くなっています。
(同じく平日で、時間帯もほぼ同じですが、違う日ではあるので単なる通信環境の違いかもしれませんが)

というわけで、Y!mobile LTEプランの帯域制限中の挙動はおそらく以下のような挙動かなと思われます。

・全体的に帯域制限される(3Mbpsくらい?)
・HTTP転送において、レスポンスヘッダに含まれるContent-Type: が特定のタイプと一致すると更に帯域制限される(96Kbpsくらい?)

ただし、帯域制限の目安の通信量をどの程度超えたかや、基地局の混雑具合によって制限値が変わるという書き込みも見られるので、数値は環境によって変わるかもしれません。

Y!mobileはHTTPのプロトコルを監視して帯域制限を行っている

旧EMOBILE LTEの回線でアプリのテストをしているときに謎の不具合として発見しました。
スピードテストや、普通のブラウジングは快適に行えているのに何故かzipファイルの転送時のみものすごく遅くなり、最初は自分のアプリの不具合を疑いましたがHTTP通信全般で発生するようです。

契約回線は旧EMOBILE LTEで、「当月のご利用通信量が10GB以上」で帯域制限を行うと公表されています。
テストした日までの通信量は10.588GBで、目安の通信量を超過している状態です。

この状態でHTTPによるリクエストを出すと、ファイル種類によって挙動が変わります。
月初めはどのような挙動になるか不明なので来月になったらやってみます。
以下実験結果です。

以下コマンドで1MBのダミーファイルを生成。
% dd if=/dev/zero of=test.zip bs=1M count=1

ファイルの中身はそのままで、拡張子のみを色々変えてwgetで転送してみた結果が以下です。

ファイルタイプ 転送時間 速度
.zip 95秒 9.68KB/s
.bin 72秒 13.1KB/s
.exe 74秒 12.6KB/s
.lzh 73秒 12.8KB/s
.7z 78秒 12.1KB/s
.rar 77秒 12.7KB/s
.jpg 2.1秒 480KB/s
.png 2.3秒 436KB/s
.pdf 2.6秒 388KB/s
.cbz 2.1秒 495KB/s
.pptx 3.1秒 335KB/s
.aikatsu 2.0秒 502KB/s

1回づつしか測定していないので誤差は大きいと思いますが、ファイルタイプによって明確な差がついていることは明らかです。10倍どころか30倍違う・・・!
1MB転送するのに1分以上もかかっているようでは、実用的にはかなりキツイ状態です。

なお、HTTPSにした場合は帯域制限かからなくなります。
(どれでも変わらないはずなのでzipのみ実験)

ファイルタイプ 転送時間 速度
zip
(HTTPS)
2.8秒 371KB/s

この結果から、Y!mobile(のEMOBILE LTEプラン)では、HTTP通信の内容を見て帯域制限を実施していることがわかります。
また、.aikatsuは制限がかかっていないので、「JPEGは制限しない」のようなホワイトリストでなく、「zipは制限する」といったブラックリスト方式みたいですね。
僕が発見したのはzip,bin,exe,lzh,7z,rarですが、他にもあるかもしれません。

次にファイルタイプの判別方法ですが、ファイルの拡張子ではなくMIMEタイプを見て判別しているようです。

.htaccess ファイルに以下を以下のようにしてMIMEタイプを変更して同じRARファイルをダウンロードした場合です。

AddType image/jpeg rar

MIME 転送時間 速度
application/x-rar-compressed 93秒 9.25KB/s
image/jpeg 2.1秒 491KB/s
www/unknown 2.7秒 376KB/s

その他、いくつかオレオレMIMEを指定してみましたが帯域制限はうけませんでした。

よって、HTTPサーバの設定を変更してMIMEタイプを変えてしまえば帯域制限を免れることができますね…。
というか最近のWebサーバはRARとかまでMIMEが正しく設定されているのか・・・。

サーバ管理者側の対策

スピードテストで測定すると速いのに、お前のサイトからダウンロードすると遅ぇよ! と、どうしていいか分からない苦情が来ることに備えるには以下の対策が考えられます。
(実際これが原因で帯域制限の仕様を知った・・・)

・HTTPSを利用する

昨今色々あるので、もう全部HTTPSにできればそれが良いかもしれません。。。

・MIMEタイプを変更する

これを変えてしまうのは反則かもしれませんが、現実的にはzipなどのMIMEが間違っていてもダウンロードさえされれば別に困りません。
ただimage/jpegなどにするとブラウザ側が困るので、www/unknownあたりにしておくのが無難かと思います。

AddType www/unknown zip
AddType www/unknown rar
AddType www/unknown exe
AddType www/unknown lzh
AddType www/unknown 7z
AddType www/unknown bin

のような感じで.htaccessファイルに書いておくだけで転送速度が30倍に! すげえ!
とりあえず、ComicGlassのサンプルファイル置き場はこの対策で乗り切ります。

もちろんブラックリストに入っているMIMEは今日現在の挙動なので今後は変わるかもしれません。
自分で薦めておいて何ですが、みんながこんなことやり始めたらHTTP崩壊だな・・・。

利用者側の対策

できることは少ないですが、HTTP通信の内容がわからなければいいわけなので、VPN接続してトンネル経由でアクセスすれば制限はかかりません。

ただ、帯域制限としては良心的な気もします。

実際に公表された通信量を超えても、HTML,JPEGやPDFなど通常のブラウジングには制限がかからないので通常の利用に弊害がありません。
また、HTTP以外の通信は特に制限されている様子はありません。

僕のようなzipをHTTP転送するのに特化されている特殊なアプリ開発者にとっては罠もいいところですが・・・。

補足

上に書いた通信速度はByte/秒です。
通信速度はbit/秒で書いてあることも多いので注意してください。

12KB/sは96kbpsになります。
400KB/sは約3.1Mbpsになります。

よって、今回のテストでも制限を受けないファイルタイプであれば3Mbps程度は出ており、たぶん制限なくてもこんなもんです。

追記(15/07/22)

いくつか補足と訂正を。

・「最近のWebサーバはRARとかまでMIMEが正しく設定されているのか・・」と書きましたが、正確には(Apacheが)/etc/mime.typesを参照してるだけですね。すみません。

・測定は平日昼間(正午ころ)行っています。夜間はプロトコル関係なく帯域制限がかかります。こちらは「24時間ごとのご利用通信量が約366MB以上の場合当日21時から翌日2時まで制限」という方にひっかかっているものと思われます。
 測定が1回づつしかやってない件については、面倒だからなんですが、数値見てもらえばわかるように1回で十分に誤差ではない有意な差が出ているので問題ないかと思います。実際体感してみればわかりますけどとんでもない差なので・・・。2秒or1分の差ですからね・・・。

・上記挙動は、記事中にも書きましたが公表された帯域制限にひっかかっている状態の話です。
 プロトコルによって帯域制限かけるのは、古くはP2Pなどで遮断はダメだけど帯域制限ならOKという方向で概ね世の中落ち着いているようなので、キャリアは真っ当な対応をしていると個人的には思ってます(ただ、帯域制限は僕の契約時には存在せず、後から導入されたものなのでキャリアとしてもあまり強く制限できない事情もあるのかもしれません)。
 一方でサービス提供者やアプリ開発者の立場からはすごく迷惑なので仕様を明確にしてユーザーに分かるようにしておいてほしいですね。

・MIMEタイプの変更は本当にやるひとはあまり居ないと思いますが、普通のWebサイトだったらやっぱ止めたほうがいいと思います。
 一方で、スマホなどのアプリ内でzipでアーカイブしたアプリ内データをHTTP使ってダウンロードするなんて仕様にしていると、「このアプリだけクソ遅いので星ひとつです。金返せ」とか書かれかねないので本当に注意が必要です。
 アプリ側を変更しないで今すぐできる対策としてはやっぱMIMEタイプ変更は、けっこういいアイデアかと思ったんですけど。
 どちらにしても、これからは「IPネットワークもはや透過的ではない」と思ってアプリケーション開発をしないといけないってことですね。崖に負けるな!

カレンダー

2024年10月
 123456
78910111213
14151617181920
21222324252627
28293031  

▲Pagetop