tizen.moe

tizen.moe

サクッとプログラムした気になる (5)

全然サクッとした気にならなくなった今日このごろですが。

やること

  • アートワークをアプリのウィンドウに表示する
    • バグを直す ←イマココ
  • 現在再生中のトラックタイトルを取得して表示する(べきだろ・・・)
  • 再生、停止、戻る、次へコントロール(別にいらないが)
  • Twitterに再生中の楽曲をポストする(最終目標)

横道にそれてリソースファイルを追加

add qrc resource file for embedding vbscript file · moguriso/gawa_sample@cdfb734 · GitHub

  • ローカルファイルを直接参照していたアホな所業を修正
  • VBScriptのファイルをgit管理に追加

バグを直す

バグの整理

Issues · moguriso/gawa_sample · GitHub
はっきりわかってるのは2件。次トラックボタンを連打するとアプリが応答不能になる問題もあったけれど、QAxScriptのentered/finishで排他制御する適当な修正で取り敢えず再現しなくなっているみたいなので外す。

修正(1)

起動時の画面サイズ調整が出来ていない · Issue #1 · moguriso/gawa_sample · GitHub

起動直後のpaintEvent(graphicsviewの方)が来ない(MainWindowsには来てるはず)のでQImageにアートワークがロードされずサイズが0x0になるのが問題っぽい。取り敢えずMainWindowのコンストラクタでQImageにアートワークを読ませてみましたが。。。

どうもupdateImageでQImageをnewしまくるバグが有る気がするのだけど不用意にdeleteするとそもそも画像がロードされなくなるので取り敢えず現状の感じに直してますが、コレも良いのかどうか、、、

要約するとなんとなく動いているけど、これでいいのか分かってません。。。

修正(2)

次トラック移動を複数回行うと画像サイズがおかしくなる場合がある · Issue #2 · moguriso/gawa_sample · GitHub

アートワークのサイズになるようにウィンドウサイズを調整しようとすると、アートワークサイズがグチャグチャでシッチャカメッチャカになるので、ウィンドウサイズにアートワークサイズをあわせる様に修正。

1.graphicsviewのサイズを強引に書き換えるだけだとジャギが目立つ(縦横比が合っててもジャギが出る)  → 真面目にラスタとか入れるか別のクラスを間に挟んで補完させるかすれば解決するのかもしれないけど   直近どうでもいいのでissueにあげて保留にする
2.ウィンドウのサイズを固定にしたかったけどやり方がわからない
 →取り敢えずサイズ変更ごとにアートワーク側のサイズを変える様にしているのでまあ良いかと

3.厳密な意味でウィンドウサイズにアートワークサイズがフィットしてない
 → そのうち直したい気はする。取り敢えず動いてるから保留。

要約すると、面倒になったので仕様の方を直しました。

タイトル表示追加

add Title display function · moguriso/gawa_sample@185c739 · GitHub
いろいろとイケテナイ感じは有るのですが、取り敢えず機能としては追加しました。

TODO

  • アートワークをアプリのウィンドウに表示する     ←対応済
    • バグを直す                     ←対応した
  • 現在再生中のトラックタイトルを取得して表示する    ←対応した
  • 再生、停止、戻る、次へコントロール(別にいらないが) ←後回し
  • Twitterに再生中の楽曲をポストする(最終目標)    ←やってみる

サクッとプログラムした気になる (4)

GUIをつけたら途端にサクッとじゃなくなりました、、、orz

機能を追加して行く予定

  • アートワークをアプリのウィンドウに表示する(べきだろ・・・)
  • 現在再生中のトラックタイトルを取得して表示する(べきだろ・・・)
  • 再生、停止、戻る、次へコントロール(別にいらないが)
  • Twitterに再生中の楽曲をポストする(最終目標)

本項の以降の文章はやったあと思い出しながら書いているので誤りを含む可能性が多々あります。

アートワークをアプリのウィンドウに表示する

処理フロー

処理の簡単な流れとしては

  1. itunesからアートワークを出力してテンポラリフォルダに置く(対応済み)
  2. テンポラリフォルダからアートワークの画像を読み込む
  3. GUIに読み込んだ画像を表示する

のが最初の流れです。追加して”次トラックに移動したら次トラックのアートワークに差し替える”とかやりたいことは色々ありますが、基本はこの流れの応用になる、はず、です。。。

デモ

ひとまず現状から書くと...もろもろバグってます。

コード

サクッとプログラムした気になる (3) - Tizen には moe ていない blogからの変更箇所はadd some function for viewing artwork on GUI · moguriso/gawa_sample@ad65a01 · GitHubの通りです。

いろいろ弄くり過ぎてシッチャカメッチャカになった感はありますが、大きな変更は下記の通りです。

  • アートワーク表示用にQGraphicsViewを追加した
  • アートワーク関連の操作をArtworkクラスにまとめた
    • ArtworkはQGraphicsViewを継承して表示部分もこれでやることにした

細かい部分まで挙げると他にもあるかも知れませんが、取り敢えずざっくりと書くとこんな感じになります。(さっくりと書くと数行ですが実際には種々の試行錯誤が含まれており云々かんぬん・・・)

アートワーク表示部分

DisplayWidgetにGraphicsViewというのがあるので、なにも考えずにそこにファイルをloadしたら表示できるのかと思ったら出来ませんでした。いろいろハマったのですが、一番大きいのは以下のエラーで

 QWidget::paintEngine: Should no longer be called  
 QPainter::begin: Paint device returned engine == 0, type: 1  

pushボタンの中でQImageをロードしてdrawImageしてたのが悪かったとのこと。
c++ - Unable to paint on Qt Widget, shows error "paintEngine: Should no longer be called" - Stack Overflow

この辺りを参考にさせていただいて諸々弄くったのが今のコードになります。。
月の杜工房 - Qt QImage画像を表示
QtでPNG画像を表示 - Narrow Escape

それとは別にハマったのが、

    Set iTunesApp = CreateObject("iTunes.Application")
    Set current = iTunesApp.CurrentTrack
    Set artworks = current.Artwork
    Set artwork = artworks.Item(1)
    format = artwork.Format

このformat、一応正しく読めているらしき情報が来る(1:jpg, 2:png, 3:bmp。3は見たことありませんが、pngは結構あります)ので

    Select Case format
        Case 1
            c_str = "jpg"
        Case 2
            c_str = "png"
        Case 3
            c_str = "bmp"
    End Select

として、出力する拡張子を変えていた所、png画像の読み込みのcaseで100%エラーが出てQImageのloadに失敗していました。なんか、改めてファイルを確認したら、pngになっている画像データの冒頭部分が

f:id:moguriso:20160615130453p:plain

JFIF:jpg画像)

ArtworkのSaveArtworkToFileの仕様(Apple公式からダウンロード出来ないので正しい仕様かどうかわからなくなってますが)は
iTunes COM Interface: IITArtwork Interface Reference
ソレによると、アートワークの画像形式は保存されているものに従う様に書かれてるので、PNGが返って来てるのにJPGになることはなさそうな気がしますが・・・。取り敢えず

	Select Case format
	Case 1
		c_str = "jpg"
	Case 2
		c_str = "jpg"
		'c_str = "png"
	Case 3
		c_str = "jpg"
		'c_str = "bmp"
	End Select

ってやったら画像が”ある”場合で読み込み失敗することはなくなりました。

アートワークが音楽データ内に存在しない場合の対応

今のままでは、そもそもアートワークが”ない”音楽データのロードで挙動不審に陥ります。なので、そもそもアートワークが無い場合には”No Image”と文字を出すように暫定修正を追加します。GraphicsViewに文字を出す部分はこちらを参考にさせて頂き

QGraphicsViewの表面にテキストを表示するサンプル · GitHub
(Atsuhiさんのgistだった)

f:id:moguriso:20160615131655p:plain:w300
お情け程度に出てますが、要改善です。

その他

割りとズブっとハマったのがVBScript側のバグで、なんかQAxScript関連でseg落ちするなと思ったら大体8割がたVBScrips側がバグってました、、、orz

TODO

  • アートワークをアプリのウィンドウに表示する
    • バグを直す ←イマココ
  • 現在再生中のトラックタイトルを取得して表示する(べきだろ・・・)
  • 再生、停止、戻る、次へコントロール(別にいらないが)
  • Twitterに再生中の楽曲をポストする(最終目標)

映画『64-ロクヨン-後編』

64-movie.jp

珍しく前後編ちゃんと観ました。viva 映画館が同じ施設内に有る仕事場。

個人的には、大どんでん返しがあったかと言われると正直無かったと思うものの
全体的に登場人物、特に三上の主観で丁寧に作られていたんじゃないかと。

重箱の隅をつつき出すと言いたいことも多々有るはありますが、言わぬが花というやつでしょう、、、



次はクリーピー観に行こうかなぁ。

サクッとプログラムした気になる (3)

作ったスクリプトを呼び出すガワを作る

スクリプトだけだとアプリケーションにならないので呼び出してくれるガワを作りました。

導入

  • Qtをインストーラー経由で入れる
  • Qt Creator起動
  • 「新しいプロジェクト」→「Qtウィジェットアプリケーション」
  • 「無題」だと怒られるので適当にアルファベットで名前をつける。取り敢えず「gawa_sample」

f:id:moguriso:20160614130112p:plain:w400
普通に入れててVS入ってない場合はMinGWだけのはずですが、VSしたい場合はチェック(デバッグ用のWindowsSDK入れないとデバッガが無いと怒られました)
残りは「次へ」→「完了」

ボタンを乗っけてslot追加

「フォーム」→「mainwindow.ui」をダブルクリック
f:id:moguriso:20160614130539p:plain:w450
こんな感じのはずなので、「Push Button」をドラックしてドロップ
f:id:moguriso:20160614130718p:plain
追加したボタンで右クリックして「スロットへ移動」
f:id:moguriso:20160614130826p:plain:w400
clicked()でOK。

VBScriptを呼び出す

地味に大変。COMのスクリプトを呼び出すのはQAxScriptManagerとQAxScriptを使うそうで、、、

QAxScriptManager Class | Active Qt 5.7

mainwindow.hを↓(addが追加部分)

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QAxScriptEngine>      //add
#include <QAxScript>            //add
#include <QDebug>               //add

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;

    QString getArtworkPath();     //add
    void nextTrack();             //add
    QAxScriptManager *m_manager;  //add
    QAxScript *m_script;          //add
};

#endif // MAINWINDOW_H

mainwindow.cppも↓な感じにいじる

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    /* add (ここから) */
    m_manager = new QAxScriptManager(this);
    bool isRegistered = m_manager->registerEngine("VBScript", "vbs");
    if(isRegistered){
        qDebug() << "OK to register VBScript";
        m_script = m_manager->load("C:\\msys64\\home\\adachi\\test.vbs", "HelloWorld");
    }
    else
        qDebug() << "NG to register VBScript";
    /* add (ここまで) */

    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    /* add (ここから) */
    if(m_script)
        delete m_script;
    if(m_manager)
        delete m_manager;
    /* add (ここまで) */

    delete ui;
}

/* add (ここから) */
QString MainWindow::getArtworkPath()
{
    QString rStr = "";

    if (m_script){
        QVariant var = m_script->call("getArtworkAndPath()");
        qDebug() << var.toString() << "loaded";
        rStr = var.toString();
        qDebug() << "rstr = " << rStr;
    }
    else
        qDebug() << "didn't load";

    return rStr;
}

void MainWindow::nextTrack()
{
    if (m_script){
        m_script->call("nextTrack()");
        qDebug() << "loaded";
    }
    else
        qDebug() << "didn't load";
}
/* add (ここまで) */

void MainWindow::on_pushButton_clicked()
{
    /* add (ここから) */
    QString path;

    nextTrack();
    path = getArtworkPath();

    qDebug() << path;
    /* add (ここまで) */
}

"C:\\msys64\\home\\adachi\\test.vbs"のところは自分のファイルに置き換えが必要です。

デモ

ちゃんと出来ていればこんな感じになるはず。

写り込みの範囲内に収まりそうにないので動画は削除しましたm(_ _)m


アプリにしようと思うと、途端に面倒くさくなりました。

サクッとプログラムした気になる (2)

itunesからアートワークを取得する

真面目にCOMのドキュメントを読んで頑張るともうちょっと込み入ったことが出来るそうです。

iTunes COM Interface: IiTunes Interface Reference

書いたスクリプト

こんな感じ。ユーザ固有のtempフォルダにjpg/png/bmpのいずれかで取得したアートワークを保存します。アートワークが無い楽曲で実行すると"artworks.Item"がNGになるのでソレ以降もNGになります。(ファイル無いので考えれば当然ですが割とハマりました、、、)

Function getArtworkAndPath()

	Dim objShell
	Dim tmp
	Dim iTunesApp
	Dim current
	Dim artworks
	Dim artwork
	Dim format
	Dim c_str

	Set objShell = CreateObject("WScript.Shell")
	tmp = objShell.ExpandEnvironmentStrings("%TMP%")

	Set iTunesApp = CreateObject("iTunes.Application")
	Set current = iTunesApp.CurrentTrack
	Set artworks = current.Artwork
	Set artwork = artworks.Item(1)
	format = artwork.Format

	Select Case format
	Case 1
		c_str = "jpg"
	Case 2
		c_str = "png"
	Case 3
		c_str = "bmp"
	End Select

	artwork.SaveArtworkToFile(tmp + "\\z." + c_str)
	getArtworkAndPath = tmp + "\\z."+ c_str

End Function

割りとウザいことにアートワークの画像形式がjpgだったりpngだったりbmpだったりするので確認して拡張子を変えてます。

デモ

次のトラックに移動する↓のスクリプトを一緒にして

Sub nextTrack()

	Dim iTunesApp

	set iTunesApp = CreateObject("iTunes.Application")
	iTunesApp.NextTrack

End Sub

ソレを実行する部分を末尾に書き足して

nextTrack
getArtworkAndPath


ちょっとプログラムした気になりました(ぉ

サクッとプログラムした気になる (1)

VBScriptitunesを操作する

前提

Windows環境前提です。VBScriptなので。

  1. 右クリック→「新規作成」→「テキスト文書」
  2. 拡張子をtxt → vbsに変更
  3. メモ帳でも秀丸でも良いので開く

"超"基本

  • コメントは ' (#とか//とか /* */ は全部NG)
  • 関数は Function or Subではじめる
    • 戻り値は Function だけ(?) 関数名に値を入れると戻り値になる

再生

Sub playTrack()
    Dim iTunesApp

    set iTunesApp = CreateObject("iTunes.Application")
    iTunesApp.Play
End Sub

playTrack

vbsをダブルクリックすると(起動していない場合はitunesが起動して)再生がはじまります。簡単。だけど、コレが出来て何なの?感がなきにしもあらず、、、

おまけ

vbsを作った要領で拡張子をbatにする。

cscript test.vbs
pause

↑な感じにしてbatをダブルクリックするとvbsがbat経由で起動する。エラーメッセージとか表示されるのでちょっとだけ便利。

デッドプール

www.foxmovies-jp.com

アメコミでは読者に話しかけ、映画では観客に話しかける、いわゆる第4の壁を超えるお方なのだそうで。CivilWarの前に流れる番宣で面白そうだったので見てしまった。まずまず面白かったけど、趣味としては64の方が好きな感じでした。なんというか、首チョンボとかバシバシ分かる形で人をスプラッタしまくるのであんまり気分が良くない。。。あと、fuckとかassとかassholeとかshitとかスラング多すぎ・・・