DebianでUniversal Media Serverを運用する

Universal Media Server (UMS)でDLNAサーバーを作った時の作業メモです。

インストール時のバージョン

  • Debian 8.2 (jessie)
  • openjdk-7-jre 7u79-2.5.6-1
  • Universal Media Server 5.2.2 for Java 7

インストール

MediaInfoとJREをインストール

sudo apt-get install mediainfo openjdk-7-jre

UMSをダウンロード

wget http://sourceforge.net/projects/unimediaserver/files/Official%20Releases/Linux/UMS-5.2.2-Java7.tgz

UMSをインストール

今回は、/opt にインストールします。

tar xzvf UMS-5.2.2-Java7.tgz
sudo mv ums-5.2.2 /opt/.
sudo chown -R root:root /opt/ums-5.2.2
sudo ln -s /opt/ums-5.2.2 /opt/ums

UMS実行ユーザーを作成

rootでUMSを動かしたくないので、umsという名前で専用ユーザーを作ります。 既存ユーザーで実行する場合は、この手順をスキップします。

sudo adduser ums

UMS実行ユーザーでの作業

UMS実行ユーザーに切り替え

sudo -i -u ums

UMSを起動する

一度起動しておくと、ホームディレクトリに設定ファイルが作られます。

/opt/ums/UMS.sh
# 起動したら、Ctrl + C で終了する

公開するディレクトリを設定ファイルに追記

UMSをインストールしたディレクトリにも設定ファイルがありますが、そちらは書き換えずにホームディレクトリの設定ファイルに記述します。

sudo vi ~/.config/UMS/UMS.conf

~/.config/UMS/UMS.confDLNAで公開するディレクトリを追記します。これらのディレクトリには、UMS実行ユーザーの読み取り権限が必要です。

folders = /path/to/video, /path/to/music, /path/to/picture

作業が終わったら、元のユーザーに戻ります。

exit

サービス化

ここまで設定が終われば、UMS実行ユーザーで/opt/ums/UMS.shを起動すると、PS3などからDLNAサーバーとして見えるはずです。

ここでは、OSを再起動してもUMSが自動起動するようにサービス化します。

Debian 8なので、systemdで設定します。

sudo vi /etc/systemd/system/ums.service

ums.serviceの内容は以下の通りです。UserはUMSを実行するユーザーに適宜変更してください。

[Unit]
Description=Universal Media Server
After=network.target

[Service]
ExecStart=/opt/ums/UMS.sh
ExecStop=/bin/kill -INT $MAINPID
ExecReload=/bin/kill -HUP $MAINPID
Type=simple
User=ums

[Install]
WantedBy=multi-user.target

サービスを有効化して、起動してみます。

sudo systemctl enable ums.service
sudo systemctl start ums.service

動作確認

再起動した後にプロセスが起動していることや、プロセスの実行ユーザーが設定通りになっているかps aux | grep umsなどで確認します。

$ ps aux | grep ums
ums      14724  0.8  2.4 3372236 189972 ?      Ssl  12月05   0:48 java -Xmx768M -Xss2048k -Dfile.encoding=UTF-8 -Djava.net.preferIPv4Stack=true -Djna.nosys=true -classpath update.jar:ums.jar net.pms.PMS

プロセスが起動していたら、PS3などで公開したディレクトリが見えるかどうか、メディアを再生できるかどうかを確認します。

Xperia sola (MT27i) 購入

Xperia sola個人輸入しました。初めての輸入だったので、注文から届くまでのことをメモしておきます。

注文

こちらこちらを参考に、1shopmobileで注文しました。
決済はGoogle checkoutを使用するのですが、送り先の住所を英語で書いておく必要があります。都道府県名を英語で表示するには、Google checkoutの設定画面で表示言語を英語に変更します。
ちなみに、住所を英語で書く方法はこちらを参考にしました。

発送

5/10(木)の夜に注文し、5/11(金)の夜に発送メールが来ました。メールにEMSの追跡番号(EA*********HK)が記載されているので、日本郵便のホームページで状況を確認できます。
追跡番号の末尾が"HK"なので、香港から発送されたことがわかります。

到着

5/12(土)には日本に到着していたようですが、土日を挟んだこともあり5/15(火)の到着となりました。
輸入にかかる税金(関税?)は届けてくれた郵便屋さんに支払います。今回は700円でした。

かかった費用

本体:$359 - 値引き:$8 + 送料:$25 = $376 でした。クレジットカードの引き落としは30552円だったので、$1 = 81.25円(手数料込)です。
これに郵便屋さんに払った税金の700円を足して、合計31252円でした。

画像

MinGW の gcc で Windows のビジュアルスタイルに対応する

Windowsアプリケーションでビジュアルスタイルを適用するには、ComCtl32.dllのバージョン6以降を使用する必要があります。
MSDNには、「YourApp.exe.manifest」というファイルを作成し、YourApp.exeと同じディレクトリに配置する方法が紹介されています。(マニフェスト外出し)

今回はこの手順を参考に、マニフェストを exe に埋め込んでみます。

[手順]

  1. InitCommonControls() を呼び出す
  2. マニフェストファイルを作成
  3. リソースファイルにマニフェストを追加
  4. ComCtl32.lib にリンク、マニフェストの埋め込み

InitCommonControls()は、最初のCreateWindow()を呼ぶ前くらいに1回呼んでおけばいいと思います。

マニフェストファイル(test.manifest)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="X86"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
</dependency>
</assembly>
リソースファイル(test.rc)
#include <winresrc.h>
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "test.manifest"

マニフェストを埋め込んだ exe を作成する

カレントディレクトリに次のファイルがあると仮定します。

  • WinMain.c
  • test.rc
  • test.manifest

ビルドコマンド:

windres --input-format=rc --output-format=coff -o test.res test.rc
gcc -c -o WinMain.o WinMain.c
gcc -mwindows -o Test.exe WinMain.o test.res -lComCtl32

まず、 windres コマンドで test.rc から test.res を作ります。--output-format=coff というオプションが重要なようです。
2行目はソースをコンパイルし、オブジェクトファイル(.o)を作成しています。
3行目でオブジェクトファイル、test.res、ComCtl32.lib をリンクしています。
test.res をリンクすることで、マニフェストファイルが埋め込まれるようです。

ビジュアルスタイルに対応したコントロールの作成方法(参考)

ちなみに、CreateWindowEx関数のdwExStyle(第1引数)にWS_EX_CLIENTEDGEを指定すると標準っぽい見た目になりました。
エディットコントロールの場合、こんな感じです。

CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
    WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL,
    10, 10, 200, 20, hWnd, (HMENU)TEXT_ID1, hInstance, NULL);

Eclipse で Win32 API プログラミング (その2)

前回はメッセージボックスを表示しただけなので、今回はウィンドウを表示してみます。

Windowsアプリケーション

前回は触れませんでしたが、Windowsアプリケーションとしてリンクするために、gcc のオプションに -mwindows を指定する必要があります。
Eclipse の場合、以下の方法で gcc のリンカオプションを指定します。

  1. プロジェクト・エクスプローラでプロジェクト名を右クリック
  2. 「プロパティー」をクリック
  3. 設定ウィンドウが開くので、「C/C++ ビルド」->「設定」->「MinGW C Linker」->「その他」にある、「リンカー・フラグ」に -mwindows と入力します
  4. OKボタンをクリックで完了


コンパイラオプション、リンカオプションなどは、この設定ウィンドウから行うことができます。

空のウィンドウを表示する

ハードディスクを漁ったら、ちょうどいいサンプルが出てきたのでそれを使います。
これは昔どこかのサイトを参考に作ったもので、なにやら処理が関数わけされています。

/* WinMain.c */

#include <windows.h>

const char APP_NAME[32] = "Test";           // アプリケーション名
const char CLASS_NAME[32] = "TestWndClass"; // ウィンドウクラス名

HINSTANCE g_hInstance;

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

BOOL RegisterWindowClass();
BOOL CreateAndShowWindow(int nCmdShow);
int MessageLoop();

////////////////////////////////////////////////////////////////////
// アプリケーションのエントリポイントです
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // インスタンスハンドルをグローバル変数へ
    g_hInstance = hInstance;

    // ウィンドウクラスを登録
    if (RegisterWindowClass() == FALSE) {
        return FALSE;
    }

    // ウィンドウを表示
    if (CreateAndShowWindow(nCmdShow) == FALSE) {
        return FALSE;
    }

    // メッセージループ
    return MessageLoop();
}

////////////////////////////////////////////////////////////////////
// ウィンドウプロシージャです
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg) {
        case WM_DESTROY: {
            PostQuitMessage(0);
            return 0;
        }
        default: {
            break;
        }
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

////////////////////////////////////////////////////////////////////
// ウィンドウクラスを登録します
BOOL RegisterWindowClass()
{
    WNDCLASS wndclass;

    ZeroMemory(&wndclass, sizeof(WNDCLASS));
    wndclass.style = CS_BYTEALIGNWINDOW | CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = g_hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = CLASS_NAME;

    // ウィンドウクラスを登録
    if (RegisterClass(&wndclass) == 0) {
        return FALSE;
    }

    return TRUE;
}

////////////////////////////////////////////////////////////////////
// ウィンドウを作成して表示します
BOOL CreateAndShowWindow(int nCmdShow)
{
    HWND hWnd;

    // ウィンドウを作成
    hWnd = CreateWindow(
            CLASS_NAME, APP_NAME,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT,
            400, 300,
            NULL, NULL,
            g_hInstance, NULL);

    if (hWnd == NULL) {
        return FALSE;
    }

    // ウィンドウを表示
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

////////////////////////////////////////////////////////////////////
// メッセージループです
int MessageLoop()
{
    BOOL bRes;
    MSG stMsg;

    while (TRUE) {
        // メッセージをキューから取り出す
        bRes = GetMessage(&stMsg, NULL, 0, 0);
        if (bRes == 0 || bRes == -1) {
            break;  // 終了する
        }

        TranslateMessage(&stMsg);   // メッセージを変換
        DispatchMessage(&stMsg);    // ウィンドウプロシージャに送る
    }

    return stMsg.wParam;
}

ソースを保存後、ビルド、実行します。
次のようなウィンドウが表示されれば成功です。

Eclipse で Win32 API プログラミング (その1)

Visual Studio Express を使えば、タダで Win32 API の練習ができる昨今、あえてEclipse + MinGW でやってみます。
というのも、今月の日経ソフトウェアEclipse + MinGW の組み合わせでも Windows 用の C/C++ 統合開発環境が作れると紹介されていて、興味本位ですw
MinGW は、GNU ツールの Windows 版で、gcc などコンパイラや Win32 API のヘッダファイルを含みます。

Eclipse のインストール

公式のものは英語版なので、次のサイトから日本語版を入手しました。

Full All in One の C/C++ パッケージには MinGW も同梱されているので、それを選択。バージョンは最新の 3.6 Helios にしました。
ダウンロードしたら解凍して、適当なフォルダにおいてやればインストールは完了です。

Hello World

それでは、eclipse フォルダの eclipse.exe をダブルクリックして Eclipse を起動します。
まず、プロジェクトを作成します。

  • プロジェクト:C プロジェクト
  • プロジェクト名:Test
  • プロジェクト・タイプ:実行可能->空のプロジェクト

次に、ソースファイルを作成します。

  • WinMain.c
/* WinMain.c */
#include <windows.h>

////////////////////////////////////////////////////////////////////
// アプリケーションのエントリポイントです
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MessageBox(NULL, "Hello World!", "Test", MB_OK);

    return 0;
}

ソースを書いたら保存し、メニューの「実行」->「実行」->「ローカル C/C++ アプリケーション」をクリックします。

デフォルトでは、「実行」すると自動的に保存・ビルドを行ってくれるようです。
メッセージボックスが表示されれば成功です。ここまでは Visual Studio とほぼ同じ手順ですね。