adbird(広告鳥) 備忘録

ffmpegでTS(m2ts)ファイルをmp4に変換

動画の変換はGUIのWinFFというソフトがシンプルで簡単だったのでそれを使っていた。

しかし、あるTSファイルをWinFFでmp4に変換したら、変換後のmp4から音声が出ない…。

あるTSファイルとはNHKの番組を録画したもので、目的の番組の前にニュースなどがちょっとだけ録画されてしまっていて、vlcで再生する際に音声がスローになってブツブツ切れてしまうファイル(界隈では結構有名な音声切り替えによるトラブル)。

TSファイルを見るだけなら、vlc再生時に一度音声を無効にしてから、また音声を有効にすればよいのだが、そのままだとファイルサイズが巨大すぎるのでmp4に変換してファイルサイズを小さくしたい。

WindowsならTsSplitterというソフトで対処できるらしい。

が、僕はUbuntuだし、わざわざwineを使ってまでWindowsのソフトを使いたくはない。

そこでいろいろ調べて、試行錯誤した結果、次のようにすれば問題のあるTSファイルでも変換できた。

シェルスクリプト

以下のような「tstomp4.sh」を作る。

# 音声エンコードなし
#ffmpeg -y -vsync 1 -i $1.m2ts -f mp4 -vcodec libx264 -map 0:0 -map 0:1 -s 1280x720 -aspect 16:9 -acodec copy -bsf:a aac_adtstoasc -ss $2 $1.mp4

# 音声ac3
#ffmpeg -y -vsync 1 -i $1.m2ts -f mp4 -vcodec libx264 -map 0:0 -map 0:1 -s 1280x720 -aspect 16:9 -acodec ac3 -b:a 192k -ss $2 $1.mp4

# 音声aac
ffmpeg -y -vsync 1 -i $1.m2ts -f mp4 -vcodec libx264 -map 0:0 -map 0:1 -s 1280x720 -aspect 16:9 -codec:a aac -bsf:a aac_adtstoasc -strict -2 -ss $2 $1.mp4

音声切り替えトラブルのないTSファイルなら、上記の「音声エンコードなし」でもいいのだが、音声切り替えトラブルがあるTSファイルの場合は「音声ac3」(ac3はDVD-Videoの音声コーデック)か「音声aac」にする。上記スクリプトでは「音声aac」にしている(それ以外はコメントアウトしている)。

  • $1 に動画ファイル名が入る。
  • map 0:0 が映像ストリーム、map 0:1 が音声ストリーム。
  • $2 に変換開始時間が入る(x秒後のところから変換する)。

実行

「tstomp4.sh」と変換したいTSファイルを同じフォルダに入れて、端末で開いて以下を実行。

sh tstomp4.sh [ファイル名。ただし、拡張子は書かない。] [変換開始時間]

例えば、hoge.m2ts というファイルの開始から5秒後のところから変換したい場合は、

sh tstomp4.sh hoge 5

とする。

ポータブックのWindows10大型アップデート

本体のストレージの容量が貧弱すぎて、Windowsの大型アップデートに失敗するポータブック

いろいろやってみた結果、以下の手順が確実で手間がかからない。

  1. 空のUSBメモリを用意(できるだけ大きな容量、今回は32GBのを使用)。
  2. 他のWindowsパソコンでMedia Creation Tool(メディアクリエイションツール)をダウンロードして、インストールメディアのUSBメモリを作成(アーキテクチャは64ビットにする)。
  3. そのUSBメモリをポータブックに挿して、「setup.exe」をダブルクリックしてあとは気長に待つ。

ほぼ以下の参照サイトなどで紹介されている方法と一緒なのだけど、メディアクリエイションツールでインストールメディアのUSBメモリを作成することが、なぜかポータブックでは失敗したので、他のWindowsパソコンで作成せざるを得なかったということぐらい。

まあ、パソコンはポータブックだけしか持っていない、なんて人はいないだろうし、ほとんどの人はポータブックとは別のメインのWindowsパソコン持っているだろうし、問題ないだろう。

ざっと手順メモ。

  • USBメモリのインストールメディアからアップデートするので、ポータブックのCドライブの空き容量は関係ないとは思うけど、バックアップも兼ねて、ドキュメント類を全部、他の場所(空のUSBメモリとは別のUSBメモリや、グーグルドライブなどのクラウドなど)に移して、Cドライブの空き容量を4GBほどにした。
  • 空のUSBメモリを挿したWindowsパソコン(ポータブック以外)で、Windows 10 のダウンロード のページヘいき、「ツールを今すぐダウンロード」をクリックして、メディアクリエイションツールをダウンロード。
  • ダウンロードしたメディアクリエイションツールの実行ファイルをダブルクリックして、実行。
  • 「実行する操作を選んでください」という画面になったら、「別のPCのインストールメディアを作成する(USBフラッシュドライブ、〜)」を選択して、次へ。
  • 「言語、アーキテクチャ、エディションの選択」という画面になったら、アーキテクチャを64ビットを選択する。
  • インストールメディアのUSBメモリが作成したら、そのUSBメモリをポータブックの方に挿して、フォルダを開いて「setup.exe」をダブルクリックしてアップデート。時間がかかるので、そのつもりで。

面倒くさがって大型アップデート(バージョン1803)をするのを後回しにし続けていて、ようやく重い腰を上げてアップデートしようとしたら、たまたまさらに新しい大型アップデート(バージョン1809)の開始日だった。

(ちなみにWindows 10 のバージョン履歴→ Windows ライフサイクルのファクト シート

そういうこともあり、最初、インストールメディアのUSBメモリの「setup.exe」を実行したら、途中、更新に失敗しましたってエラーが一度出たものの一応はアップデートは終わったので、確認したらバージョン1709…。

もう一度「setup.exe」を実行したら、今度はうまく行き、ちゃんと最新のバージョン1809になった。

Vivaldi 2.0 埋め込みのhtml5動画の音量調整を表示する

Vivaldiブラウザをバージョンアップしたら、埋め込みのhtml5動画(WebM 等)の音量がオン/オフしかできずに、音量調整ができなくなっていた。

例えば、このサイト→ HTML5 Video で確認すると、音量調整ができないのが分かると思う。

↓これはVivaldiブラウザだけでなく、Chromeの方でも同じらしい。

 Google Chrome ヘルプ フォーラム 動画の音量が調整できません。

上記リンク先の情報を参考に、アドレスバーで下記にアクセスし、

vivaldi://flags/#enable-modern-media-controls

の「New Media Controls」をDisabledにして再起動したら、音量調整ができる古いUIになって、問題解決( HTML5 Video でもう一度確認)。

きっとそのうち上記作業をしなくても音量調整ができる新しいUIがでてくるんだろうけど。

バイクのオイル交換2回目

もうすぐ1万キロに到達するDトラッカー125のオイル交換&エレメント交換。

今回、総走行距離9963kmにて交換。
前回は総走行距離7044kmで交換したので、2919kmで交換したことになる。

利用している電子書籍サービスまとめ

キャンペーンなどで様々なポイントをもらったり、Tポイントなどが貯まったりした時に電子書籍を買うことが多いのだが、各々、ポイントが使える電子書籍サービスが限定されているので、結果的にいろんな電子書籍サービスで電子書籍を買うはめになって、「あの本、どこで買ったかな?」となるので、利用している電子書籍サービスをまとめる。

余談。
Yahoo! JAPAN IDとTポイントを連携させておくと、Tポイントで電子書籍購入だけなくYahoo! JAPANサービスでいろいろ使えるので何かと便利。
前述の通り、日常の買い物等をクレジットカードのYahoo! JAPANカードで支払えば、Tポイントがどんどん貯まるし。

Yahoo! JAPANサービス たまる・使えるところ

VivaldiブラウザのWebパネルに簡易メディアプレイヤーを追加

概要

VivaldiブラウザのWebパネルにYouTubeやストリーミング系の音楽サイトを表示して、音楽を再生するってのは見かけるけど、ローカル(自分のPC内)にある音楽データを再生してくれる音楽プレーヤーをパネルに表示できないだろうか?(Operaブラウザにかつてあった「音楽パネル」が念頭にあったw)といろいろ調べたところ、以下の方法でできた。

追記:

これを作った後に、 Winamp2-js の存在を知りました。機能的にはたぶん、そちらのほうが幸せになりますw。

ただし、Winamp2-js だと、動画の音声は再生できるけど、映像は表示できないっぽいです。

ここで紹介する方法では、もちろん、映像も含めて、動画の再生が可能です!
それぐらいしか強みはないです…。
あとは表示がシンプルで見やすいというところぐらいしか…w。

Winamp2-js についての個人的感想としては、Winampは昔、お世話になってたけどやはりデザイン的に古いなぁと思ったのと(スキンが代えられるのは知っているけど)、操作ボタン・フォント等が小さすぎ、そして、「(パネルじゃなくて)Winampで再生してる」って感じがして、ちょっと違うかな…ってなった(^_^;)。

更新

  • Windowsの方への注意事項(html保存の際に UTF-8 に)追加。(2018/4/8)
  • 「開く/追加」ボタンを追加、その他CSS修正。(2018/3/27)
    • @z7wacg2u さん、本当にありがとうございました!
  • htmlソースを一部修正 (2018/3/25)
    • プレイリストの曲名に番号が付くようにした。
    • 背景色・フォント色を変更。
    • tableタグを削除して、パネルの幅に合わせてプレイヤー・動画が拡大・縮小されるようになった。
  • Webパネルにアイコンが表示されるように修正。(2018/3/22)
    • ※表示されたり、されなかったりと動作が不安定です…。
  • パネルを狭めると「次へ」が隠れるので、再生曲名の下に「次へ」ボタンが来るように修正。

Webパネル用のアイコンを保存

(※追記:原因は不明ですが、アイコンが表示されたりされなかったりします…。不安定なため、このプロセスは飛ばしてもらって構いません。)

なくてもいいのだけど、Webパネルにアイコンが表示されないのが寂しかったので、アイコンが表示されるようにする。

【フリーアイコン】 再生 あたりから、適当に好きなアイコンをもらってきて、保存。

ここでは「再生アイコン.png」として保存。
32px(ピクセル)× 32px の大きさにするのがいいっぽい。

後述のhtmlソースの、以下の部分で指定すれば、アイコンが表示される(表示されなかったら、いったんWebパネルから削除して、もう一度Webパネルに追加すれば表示されるはず)。

  <!-- パネルのアイコン画像 -->
  <link rel="shortcut icon" type="image/png" href="再生アイコン.png">

htmlファイル を保存

下記リンク先にアップしたhtmlをローカル(自分のPC)に保存するか、

下記のソースを「mediaplayer.html」として保存。

Windowsの方は保存の際に、文字コードUTF-8 にして保存しないと、「開く/追加」「次へ」ボタンが文字化けするかもしれません。

いまさらHTML5 (簡易プレイヤー編)」のhtmlソースがほぼそのままのベースとなっています。また、@z7wacg2u さんに「開く/追加」ボタンのJavaScriptの編集をしていただきました。

適宜、前述のアイコン画像ファイルのURLや、デフォルトの音量部分を編集すること。

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <!-- パネルのアイコン画像 -->
  <link rel="shortcut icon" type="image/png" href="再生アイコン.png">

  <title>メディアプレイヤー</title>
  <style>
    /* 背景色 フォント色 */
    body{background-color:#E1DDD8;
      color:#4F4F4F;}
    .nowplaying{margin-top:5px;
      margin-left:5px;
      margin-bottom:5px;}

        label {color: #E5E5E5;  
            background-color: #7D7D7D;
            margin:0 0 0 5px;
            padding: 4px 6px;
            border-radius: 5px;
            font-size:9pt;}
    .openbutton{display:none;}
    .nextbutton{float:right;
                display:block;
                border-style: none;
                background-color: #7D7D7D;
                color: #E5E5E5;
                margin:0 5px 3px 0;
                padding:3px 15px;
                border-radius: 5px;
                font-size:9pt
}

  </style>
  <script type="text/javascript">
    // VIDEOタグ
    var video = null;
    // AUDIOタグ
    var audio = null;
    // ファイル一覧
    var list = [];
    // 初期処理
    function init() {
      // ファイルドロップイベント設定
      document.getElementById("drop").addEventListener("dragover", eventStop, false);
      document.getElementById("drop").addEventListener("drop", filedrop, false);
      // VIDEOタグ取得
      video = document.getElementById("video");
      // 終了イベント取得設定
      video.addEventListener("ended", playerEvent, false);
      // VIDEO非表示
      video.style.display = "none";
      // AUDIOタグ取得
      audio = document.getElementById("audio");
      // 終了イベント取得設定
      audio.addEventListener("ended", playerEvent, false);
      // AUDIO非表示
      audio.style.display = "none";
      // 次へボタン押下イベント設定
      document.getElementById("next").addEventListener("click", next, false);
      // 次へボタン非表示
      document.getElementById("next").style.display = "none";
      // ファイル選択ボタンのイベント
      document.getElementById("openfile").addEventListener("change", open, false);
      // キーイベント
      document.onkeydown = key_event;
    }
    // ショートカットキー
    function key_event() {
      var code = event.keyCode;
      switch(code) {
        // Space
        case 32:
          // audioの再生と一時停止Toggle
          if (audio.paused) audio.play(); else audio.pause();
          // videoの再生と一時停止Toggle
          if (video.paused) video.play(); else video.pause();
          break;
        // N
        case 78:
          next();
          break;
      }
    }
    // ファイルがドラッグされた場合
    function eventStop(event) {
      // イベントキャンセル
      event.stopPropagation();
      event.preventDefault();
      // 操作をリンクに変更
      event.dataTransfer.dropEffect = "link";
    }
    // ファイルがドロップされた場合
    function filedrop(event) {
      try {
        // イベントキャンセル
        event.stopPropagation();
        event.preventDefault();
        // ファイル存在チェック
        if (event.dataTransfer.files) {
          var old = list.length;
          // ファイル一覧取得
          var files = event.dataTransfer.files;
          // ファイル数分ループ
          for (var i = 0; i < files.length; i++) {
            // ファイル取得
            var file = files[i];
            // 再生可能ファイルであるか判定
            if (video.canPlayType(file.type) || audio.canPlayType(file.type)) {
              // ファイル情報生成
              var item = {
                name: file.name,
                type: file.type,
                url: URL.createObjectURL(file)
              };
              // ファイル追加
              list.push(item);
            }
          }
          // 表示
          view();
          // 最初であるか判定
          if (old == 0 && list.length > 0) {
            // 次へボタン表示
            document.getElementById("next").style.display = "block";
            // 次を再生(最初)
            next();
          }
        }
      } catch (e) {
        // エラーの場合
        alert(e.message);
      }
    }
    // ファイルを開く
    function open() {
      var fileRef = document.getElementById("openfile");
      if (fileRef.files) {
        var old = list.length;
        // ファイル一覧
        var files = fileRef.files;
        for (var i = 0; i < files.length; i++) {
          // ファイル取得
          var file = files[i];
          // 再生可能ファイルであるか判定
          if (video.canPlayType(file.type) || audio.canPlayType(file.type)) {
            // ファイル情報生成
            var item = {
                name: file.name,
                type: file.type,
                url: URL.createObjectURL(file)
                };
            // ファイル追加
           list.push(item);
          }
        }
        // 表示
        view();
        // 最初であるか判定
        if (old == 0 && list.length > 0) {
          // 次へボタン表示
          document.getElementById("next").style.display = "block";
          // 次を再生(最初)
          next();
        }
      }
    }
    // 次を再生
    function next() {
        // ファイル数チェック
        if (list.length > 0) {
            // 最初のファイルを設定
            var item = list[0];
            // ファイル数分ループ
            for (var i = 0; i < list.length; i++) {
                // VIDEOタグかAUDIOタグと一致するか判定
                if (video.src === list[i].url || audio.src === list[i].url) {
                    // 最後のファイルか判定
                    if (i != list.length - 1) {
                        // 次のファイルを設定
                        item = list[i + 1];
                        break;
                    }
                }
            }
            // AUDIO停止
            audio.pause();
            // VIDEO停止
            video.pause();
            // タイプ判断
            if (item.type.indexOf("audio/") == 0) {
                // AUDIOなので、VIDEO初期化
                video.src = "";
                video.style.display = "none";
                // AUDIO表示
                audio.style.display = "block";
                // 前回とURLが異なるか判定
                if (audio.src != item.url) {
                    // URL更新
                    audio.src = item.url;
                }
                // AUDIO再生
                audio.play();
                // デフォルトの音量調整 0〜1.0
                audio.volume = 0.5;
            } else if (item.type.indexOf("video/") == 0) {
                // VIDEOなので、AUDIO初期化
                audio.src = "";
                audio.style.display = "none";
                // VIDEO表示
                video.style.display = "block";
                // 前回とURLが異なるか判定
                if (video.src != item.url) {
                    // URL更新
                    video.src = item.url;
                }
                // VIDEO再生
                video.play();
                // デフォルトの音量調整 0〜1.0
                video.volume = 0.5;
            }
            // ファイル名表示
            document.getElementById("playfilename").textContent = item.name;
        }
    }
    // イベント取得
    function playerEvent(event) {
        // イベントタイプ判定
        if (event.type == "ended") {
            // 終了なので、次へ
            next();
        }
    }
    // 表示
    function view() {
        // 表示されているリスト取得
        var nodes = document.getElementById("playlist").childNodes;
        // 全部削除
        while (nodes.length > 0) {
            document.getElementById("playlist").removeChild(nodes[0]);
        }
        // リスト数分追加 番号なし表示
        /*
        for (var i = 0; i < list.length; i++) {
          var div = document.createElement("div");
          div.textContent = list[i].name;
          document.getElementById("playlist").appendChild(div);
        }
        */
        // リスト数分追加 番号あり表示
        for (var i = 0; i < list.length; i++) {
            var li = document.createElement("li");
            li.textContent = list[i].name;
            document.getElementById("playlist").appendChild(li);
        }
        // 表示幅調整
        document.getElementById("playlist").style.width = "100%";
    }
    // ロードイベント登録
    window.addEventListener("load", init, false);
  </script>
</head>
<body>
  <div id="drop" style="position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; overflow: auto;">

    <!-- ファイル名 -->
    <div id="playfilename" class="nowplaying"></div>

    <!-- ファイルを開く -->
    <label for="openfile">
    開く/追加
    <input id="openfile" type="file"  class="openbutton" accept="audio/*,video/*" multiple />
    </label>

    <!-- 次へ部分 -->
    <button id="next" class="nextbutton">次へ</button>
    <!-- プレイヤー部分 -->
    <div style="resize: both; overflow: auto; width: 100%;">
        <video id="video" controls style="width: 99%; height: 99%;"></video>
        <audio id="audio" controls style="width: 99%; height: 40px"></audio>
    </div>

    <!-- ドロップ&一覧部分 番号なしで表示したい場合はこちら。
    <div id="playlist" style="width: 100px; height:; overflow: auto;"></div>
    -->
    <!-- ドロップ&一覧部分 番号つきで表示-->
    <ol id="playlist" style="width:; height:; overflow: auto;">
    </ol>
  </div>
</body>
</html>

デフォルトの音量調整

デフォルトの音量を調整したい場合、上記htmlソースのこの部分を書き換えてください。

 // デフォルトの音量調整 0〜1.0
 audio.volume = 0.5;

(中略)

// デフォルトの音量調整 0〜1.0
video.volume = 0.5;

Webパネルに追加

Vivaldiブラウザで「mediaplayer.html」を開いて、ウェブパネルに追加。

音楽データや動画データをドラッグ・アンド・ドロップ
または
「開く/追加」ボタンをクリックして、追加

すれば再生される。

プレイリストをクリアしたい場合は、Webパネルのツールバー(※1)の「再読み込み」か「ホームページへ移動」のボタンを押す。

※1:
表示されていなかったら、ウェブパネルのアイコン上で
 右クリック > ツールバー > 表示
 右クリック > ツールバー > 全てのコントロールを表示
で表示する

こんな感じ

こんな感じにブラウザで音楽再生が可能に。僕はウェブパネルを右側に表示している。

f:id:adbird:20180327171320p:plain

他力本願な願い… 願いがかなった!

僕は htmlとcssは少しは分かるけど、JavaScript はさっぱりなので(音量調整のやつはネットで調べて偶々うまくいっただけ)、どなたか、ボタンを押せば、フォルダダイアログが開いて、プレイリストにファイルを追加する機能の「開く/追加」ボタンを作ってくれないだろうか…。
ドラッグアンドドロップのためにわざわざファイルマネージャを開きたくない。

@z7wacg2u さんからJavaScriptソースの提供をいただき、「開く/追加」ボタンが付きました!

これでフォルダダイアログが開いて、ファイルが追加できるようになりました!
もちろん、これまでどおり、ドラッグアンドドロップでの追加でもできます。

@z7wacg2u さん、本当にありがとうございました!

Geanyエディタのテーマ

テーマをインストール

$ git clone https://github.com/codebrainz/geany-themes
$ mv ./geany-themes/colorschemes ~/.config/geany/
$ rm -r ./geany-themes

テーマの変更

Geanyを起ち上げている場合は、一度閉じて、もう一度起ち上げ直す。

表示 > エディタ > 色の設定

で、テーマを選ぶ。

参照:[Ubuntu 16.04] Geany のテーマ(Color scheme)を変更する。