OBS-Studio+Radeon ReLiveでストリーミングができなかった話

OBS

つい最近AMDよりRadeon Software Crimson Reliveとやらが配信されたようです。
こやつはこれまでのRadeonドライバに多数の機能追加を行ってバージョンアップ版としてリリースされました。
Radeonユーザーはアップデート画面が出てきたのにバージョン下がっとるがな!と思うかもしれません。

さて、本題です。

アップデートしたらOBSで放送できなくなった!!

そうです。放送できなくなったのです。
と言っても、ログを確認してそれを頼りに英語ページを調べていくうちに解決しました。

ログはここにあると思います。
C:\Users\user\AppData\Roaming\obs-studio\logs

[AMF Encoder] <Plugin::AMD::VCEEncoder::SetFullColorRangeEnabled> Setting to Enabled failed with error AMF_INVALID_ARG (code 4).
[AMF Encoder] Exception: <Plugin::AMD::VCEEncoder::SetFullColorRangeEnabled> Setting to Enabled failed with error AMF_INVALID_ARG (code 4).
[AMF Encoder] Unable to create Encoder, see log for more information.

こんな感じのエラーが出てます。
まぁエンコードできねーんだけど…って怒ってるわけですね。

とりあえず解決法をどばーっと

githubにて最新のエンコードプラグインを公開してくれています。

https://github.com/Xaymar/obs-studio_amf-encoder-plugin/releases/tag/1.4.3.3

つまり使えないなら差し替えればいいじゃないという話です。
enc-amf.dll
enc-amf.pdb
他にも色々と差し替えますが、主にこの2つが重要です。
\obs-plugins\32bit\とかにあります。

osbplugin

これをダウンロードしてOBSのインストールフォルダを指定して実行すれば完了です。

ログ見ればすぐに解決できることですが、情報があればもっと早く解決できますね。感謝感謝。

スプレッドシート+メール通知

今回したいこと

スプレッドシートで管理しているソフト等の更新日が近くなったらメールを送りたい。
更新日が迫っているものの一覧が欲しいだけ。

早速作る

まずはスプレッドシートを作成して良いように設定。

すぷれっどしーと

以下コードを作ったスプレッドシートのGASにぶっこむ。

//メイン処理
function Main() {
  var wkData = getValue();
  var message = "";
  for(key in wkData){
    message += key + ":" + wkData[key] + "\n";
  }
  
  if(message != ""){
    sendMail(message);
  }
}

//ID列をキーにして連想配列に格納する
function getValue() {
  var sheet = SpreadsheetApp.getActive().getSheetByName('シート1');
  var endRow = getLastRowNumber(sheet);
  var values = sheet.getRange(2,1,endRow-1,5).getValues();
  var data = {};
  for (var i = 0, l = values.length; i < l; i++) {
    var key = values[i].shift();
    if (key.length > 0) {
      if (isDateConvertCheck(values[i][1])){
        var today = new Date();
        var yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
        var nowDate = Utilities.formatDate(yesterday,'JST','yyyyMMdd');
        var wkDate = Utilities.formatDate(values[i][1],'JST', 'yyyyMMdd');
        
        if (wkDate > nowDate){
          continue;
        }
        
        var rtDate = Utilities.formatDate(values[i][2],'JST', 'yyyy年M月d日');
        values[i].splice(1,4);
        values[i][1] = "プロダクト期限:" + rtDate;
      }
      data[key] = values[i];
    }
  }
  return data;
}

//メールの送信
function sendMail(message) {
  GmailApp.sendEmail("メールアドレス(カンマ区切りで複数宛先)","プロダクト更新時期通知",message);
}

//変換出来るかチェック
function isDateConvertCheck(date){
  try{
    var cvDate = Utilities.formatDate(date, 'JST', 'yyyy年M月d日');
    return true;
  } catch(e){
    return false;
  }
}

//入力されている最終行の取得
function getLastRowNumber(sheet){
 var last_row = sheet.getLastRow();

 for(var i = last_row; i >= 1; i--){
  if(sheet.getRange(i, 2).getValue() != ''){
   return i;
    }
 }
}

後はトリガー設定して定期実行させるだけ。
ね?簡単でしょう?

受信したメールはこんな感じ。

mail

Fromがスクリプトを動かすユーザのメールアドレスになるので、個人や社内利用向けかなぁ。

IFTTTを使ってGmailをスプレッドシートに転記

最近流行りのIFTTTを使ってGmailとスプレッドシートを連携させてみました。

IFTTTとは

テンプレートを作って多数のWebサービスを連携させるサービスです。
例えばタイトルにもある通り、Gmailの受信メールをスプレッドシートに転記するとか。
IFTTTはここからアクセス
ちなみにイフトと読むそうです。

では今回の目玉である連携にいきましょう。

そもそもまともな状態で転記されない問題

連携するのに初端からコケてるじゃねーか!

まともではないというのは、転記時にメールの受信日付が独自のもので記入されてしまう所です。
例えば
May 14, 2016 at 05:12AM
こんな感じ。

ソートできませんよね。困りますよね。

ではこれを解決するにはどうしたら良いのか?
とりあえず思いつくのは何個かありますが、正規表現で抜き取っていくのが楽かもしれません。
ただ、この場合は書式が変わると対応に追われて死にます。
なので応急処置的なものだと考えてます。
(IFTTTとGmailやスプレッドシートを連携する方法は他で調べてね)

早速ポチポチ関数を使って引き抜いていく

想定は1行目に列名を入れて、日時はA2に格納されている状態。

E2セル =F2&"-"&G2&"-"&H2&" "&J2 //フィルタ用日時格納セル
F2セル =REGEXEXTRACT(A2,"[0-9][0-9][0-9][0-9]") //年
G2セル =VLOOKUP(REGEXEXTRACT(A2,"[A-Za-z]+"),month_table!A$1:B$12,2,FALSE)//月
H2セル =REGEXEXTRACT(A2,"[0-9]+")//日
I2セル =REGEXEXTRACT(A2,"[0-9]+:[0-9]+")//時刻(12時)
J2セル =IFERROR(IF(FIND("PM",A2,1)>0,IF(MINUTE(REGEXEXTRACT(I2,"[0-9]+:[0-9]+"))<10,IF(HOUR(I2)=12,HOUR(REGEXEXTRACT(I2,"[0-9]+:[0-9]+"))&":0"&MINUTE(REGEXEXTRACT(I2,"[0-9]+:[0-9]+")),HOUR(REGEXEXTRACT(I2,"[0-9]+:[0-9]+"))+12&":0"&MINUTE(REGEXEXTRACT(I2,"[0-9]+:[0-9]+"))),IF(HOUR(I2)=12,HOUR(REGEXEXTRACT(I2,"[0-9]+:[0-9]+"))&":"&MINUTE(REGEXEXTRACT(I2,"[0-9]+:[0-9]+")),HOUR(REGEXEXTRACT(I2,"[0-9]+:[0-9]+"))+12&":"&MINUTE(REGEXEXTRACT(I2,"[0-9]+:[0-9]+")))),""),IFERROR(IF(FIND("12:",I2,1)>0,IF(MINUTE(REGEXEXTRACT(I2,"[0-9]+:[0-9]+"))<10,"00:0"&MINUTE(REGEXEXTRACT(I2,"[0-9]+:[0-9]+")),"00:"&MINUTE(REGEXEXTRACT(I2,"[0-9]+:[0-9]+"))),""),REGEXEXTRACT(I2,"[0-9]+:[0-9]+"))) //時刻(24時)

最後だけ大変長くなっています。
これは0埋めとAM、PM変換のためです。AM12時なら12を足して0時になります。

ここまで記入していざテストする段階で気づくことがあると思います。ない?残念です。

それはIFTTTには入力された行をスキップする機能があるです。
実際めちゃくちゃ困りました。

とりあえずGAS(スクリプト)で解決を目指す

IFTTT側に設定した列を使用しないとしても、入力された行をスキップする機能を殺せないので
GAS(Google Apps Script)を使うことにします。

function SetCode() {
  var ss=SpreadsheetApp.getActiveSpreadsheet(); //スプレッドシートを取得
  var sheet=ss.getSheetByName("シート1"); //シートを取得
  var maxRow=sheet.getDataRange().getLastRow(); //シートの使用範囲のうち最終行を取得
  var code1 ='';
  var code2 ='';
  var code3 ='';
  var code4 ='';
  var code5 ='';
  var code6 ='';
            
/* スプレッドシートの入力が完了しているかをチェック */
  for(var i=2;i<=maxRow;i++){
    code1 ='=F'+i+'&"-"&G'+i+'&"-"&H'+i+'&" "&J'+i+'';
    code2 ='=REGEXEXTRACT(A'+i+',"[0-9][0-9][0-9][0-9]")';
    code3 ='=VLOOKUP(REGEXEXTRACT(A'+i+',"[A-Za-z]+"),month_table!A$1:B$12,2,FALSE)';
    code4 ='=REGEXEXTRACT(A'+i+',"[0-9]+")';
    code5 ='=REGEXEXTRACT(A'+i+',"[0-9]+:[0-9]+")';
    code6 ='=IFERROR(IF(FIND("PM",A'+i+',1)>0,IF(MINUTE(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+"))<10,IF(HOUR(I'+i+')=12,HOUR(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+"))&":0"&MINUTE(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+")),HOUR(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+"))+12&":0"&MINUTE(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+"))),IF(HOUR(I'+i+')=12,HOUR(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+"))&":"&MINUTE(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+")),HOUR(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+"))+12&":"&MINUTE(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+")))),""),IFERROR(IF(FIND("12:",I'+i+',1)>0,IF(MINUTE(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+"))<10,"00:0"&MINUTE(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+")),"00:"&MINUTE(REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+"))),""),REGEXEXTRACT(I'+i+',"[0-9]+:[0-9]+")))';

    var code = [code1,code2,code3,code4,code5,code6];
    
      if(sheet.getRange(i,1).getValue()!=""){ 
        if(sheet.getRange(i,5).getValue()==""){
          var a=0;
          for(var j=5;j<=10;j++){
            sheet.getRange(i,j).setFormula(code[a]);
            a++;  
          }
          a=0;
        }
      }
  }
}

面倒なので相当雑なプログラムになっています。
こいつをGASでポチポチっと作ってトリガーを時間単位で設定します。
編集時に動かしたかったのですが、どうしてもトリガーが動かないなら定期的に実行すればいいか
くらいの気分です。

ここで共有してます。閲覧のみなのでマイドライブに追加→コピーでもして使ってみてください。

以上!

2016/12/08追記
どうやら正規表現のミスがあったようなので修正しましたよ。
AM12時=0時
PM12時=12時
たまに米国の悪しき慣習に引きづられそうになりますが。

SB X-Fi Series Support Packを使ってみた

ONKYOが送り出したSE-300PCIEがそれなりにこなれてきたようで…
ドライバその他諸々が不調に。

今回はドライバそのものをそっくり変えてしまう方法を取りました。

何をするの?

変えると言っても自分でコードをバリバリ書いて作るわけではなく、
非公式のドライバを使って修正できたら良いなぁという感じ。

つまり、既存のドライバ類をアンインストールしたあと、
非公式ドライバをダウンロードしてインストールするだけ!
ほら簡単でしょう?

非公式ドライバとは

Creative系の公式ドライバが合わない(エラー吐いたりする)人が多数出ているので、
有志の方が非公式でドライバを作るというクリエイティブな状況が出来上がっています。
公式なんとかしろよ!と叫びたいところですが。

今回はこの人の公開しているドライバを使います。
最新バージョンは3.7です。(2015.12.17現在)
リンクだよ。

まぁ、ドライバを入れなおすということで、
英語くらいは理解するか翻訳しようぜ!
→ダウンロードできる箇所や注意事項などは省きます。

実際やることはポチポチ押すだけ

他の作業をしつつダウンロードしておいて、
既存のドライバやゴミファイルをアンインストール&完全に削除

再起動&オンボードサウンドをオフ

先ほどダウンロードしたファイルから起動

インストール!

x-fi3.7

途中フルインストールするかどうか聞かれるので、カスタムインストールを選ぶ。
画像の通りにする必要はないので、お好みに。

インストールできたら再起動して動作確認します。

実際には

他にも色々と使っているのでインストールするものは別にありますが、
サウンドカードさしてドライバインストールして使うだけという人は特に何もいらないと思います。

以上!