Saturday, June 22, 2019

Audioファイルを取り扱う




CDの音楽を取り込むのにApple Lossless形式を用いていたが,現在使用しているカーナビは
Apple Lossless形式を再生することができない。スマートフォンのBluetoothで飛ばせばいい
じゃんというが,普段はドライバーなので運転中にスマートフォンを操作するのは難しい。
できれば,sdカードに保存しておいてジュークボックスみたいに音楽を再生していきたい。


まずは変換対象となるaudioファイルをリストアップすることから始めた。
Python3のffmpeg-python packageffmpeg.probe を使ってaudioファイルかどうかを判定する。


for fname in file_list:
   full_path = os.path.join(dir_path, fname)
   try:
       js = ffmpeg.probe(full_path)
       if js['streams'][0]['codec_type'] == 'audio':
           self._filelists.append({ "path" : full_path,
                                    "probe" : js })
   except ffmpeg._run.Error:
       pass

これで自分が所持しているaudioファイルのリスト,およびcodecを調べることができた。

次はApple Losslessファイルだけを抽出し,flac形式に変換してみる。


ここまでの実装は github 上にpushした。



Tuesday, August 13, 2013

電子コミックの文字問題

既知の問題だけど,電子書籍でコミックを読む場合の辛さはあります。

書き文字の 日本では改名した,●ーダフォン社から。 の「改名」が潰れていて読むのが大変なことと,吹き出しの文字も結構潰れていますね。
書き文字,吹き出しをどのように見せるか,下から引き出したときにテキストデータが見えるようにするか,じゃどのようにデータを用意するか,大変だけどそこまで求められているか,高解像度でスキャンできれば解決できるのか,皆さんいろいろたどった道ですが,どのように改善できるのかだと思います。

これ紙版との比較する必要がありますが,部屋のどこにあるのか探しだせていないです。

Thursday, November 03, 2011

android関連のarticleは11月6日までに全削除いたします。

Tuesday, July 26, 2011

Hack for Japan 遠野会場へ行ってきました

遠野でのHack For Japanイベントに行ってきました。




作ったもの





36:30ぐらいから。

コメントとして,

  • 状況は変化していくので,updateもできるような機能がほしい
  • PersonFinderと連携してほしい
  • 緊急退避情報として,現在地付近のこれまでの津波の高さ(「波高」,「浸水高」,「遡上高」?)を表示して,近くの高台の場所を緊急避難場所として表示する。過去の教訓をもとにした資料に,1時間は動くなという石碑があったのでそれを参考に。

(不足していたらご指摘いただけませんでしょうか)などがあり,今後の課題とします。

改善点

開発環境の準備

今回,現地でAndroid SDKをインストールしたのですが,Step 4のAdding Platforms and Other Componentsで,全てのコンポーネントをインストールしようとして,この作業で1,2時間ぐらいかかった。今回,アイデアソンでしゃべった内容を当日作ることになったので,必ずしも全員が開発環境わけではないので,できれば事前告知しておけばよかった。

妥協リストの作成

まずは動くものを成果物にあげようというコンセプトで,実装する際に妥協したこともあった。たとえば,設定項目(送信先メールアドレス,SMS送信先電話番号)は,保存できていない。このリストを共有できれば,後日協力者を集めるのに役立てられるだろう。

今回遠野まごころネットさんの方とお話する機会があり,支援物資管理などICTの技術が利用できるところは多々あるが,瞬発力も必要ということで,速やかに動くものを提供する,柔軟に変更点に対応するなど,表に出てくることが必要かと思う。

Wednesday, May 18, 2011

Google APIs Client Library for JavaのAndroid向けライブラリのソースを公開しました。

英語版の日本語版です。


Google APIs Client Library for Java
のAndroid向けライブラリのソースを公開しました。
(URL は http://code.google.com/p/android-library-google-api-java/ です。)


単に,Google SpreadSheets に対して,OAuth 1.0a で

  • 新しいSpreadSheetの作成
  • worksheet entryの追加
  • セルの更新
ができます。他のサービスについても作成していきますが,なんせあまりいいエンジニアじゃないので,スピードは相当遅いです。JavaDocも何も作成していなくて申し訳ございません。 何か,要望,提案や間違いの指摘,バグレポートがありましたら こちらよりご連絡ください。

Published my android library to use Google APIs Client Library for Java

I upload sources of my android library to use Google APIs Client Library for Java.


This is a just sample for Google Spread Sheet, but it can create new spreadsheet and worksheet, rename the title of worksheet entry, and put cells on your worksheet with OAuth1.0a.


URL is http://code.google.com/p/android-library-google-api-java/.


I am preparing JavaDoc and classes for other services. But I am not good engineer, so speed to update migh be very slow.


Please contact me if you have any requests, suggestions, corrections and bug reports.

Sunday, May 08, 2011

Google Spreadsheets を Androidから扱う (5) DataModelの定義

Google-API-Java-Clientを用いて,Google Docsにアクセスするためには,GData-Java-Clientとは異なり,自分でデータモデルを定義する必要があります。

First, you need to invest in writing a custom data model for the Google API. Please read the JavaDoc for the new XML data model in google-api-java-client.

参照元 (What if I have a larde code base that uses gdata-java-client)

ここでは,次のfeedを表すデータモデルを具体的に定義してみましょう。feed は
QueryResponses
に掲載されているデータを利用しました。



  http://www.example.com/feed/1234.1/posts/full
  2005-09-16T00:42:06Z
  Books and Romance with Jo and Liz
  
  
  
  
  
    Elizabeth Bennet
    liz@gmail.com
  
  Example Generator Engine
  2
  0
  
    http://www.example.com/feed/1234.1/posts/full/4521614025009481151
    2005-01-09T08:00:00Z
    2005-01-09T08:00:00Z
    
    This is the title of entry 1009
    
      
This is the entry body of entry 1009
Elizabeth Bennet liz@gmail.com
http://www.example.com/feed/1234.1/posts/full/3067545004648931569 2005-01-07T08:00:00Z 2005-01-07T08:02:00Z This is the title of entry 1007
This is the entry body of entry 1007
Elizabeth Bennet liz@gmail.com

まず,root要素 feed について定義していきます。

public class GoogleDocFeed {
    // TBD
}

feed要素の属性にある名前空間に関係した属性,"xmlns:atom","xmlns:openSearch","xmlns:gd" は今回扱いません。
一方,属性 "gd:etag" は今後使うことも考慮して,データモデルを定義します。
import com.google.api.client.util.Key;

public class GoogleDocFeed {
    @Key("gd:etag")
    public string gd_etag;
    // TBD
}

つぎに,<id>http://www.example.com/feed/1234.1/posts/full</id> のように,属性を持たず,かつ内部に子要素を含まない要素の
データモデルを定義していきます。

    @Key  
    public string id;      // for http://www.example.com/feed/1234.1/posts/full

    @Key  
    public string updated; // for 2005-09-16T00:42:06Z

つぎに,link要素を定義していきます。feed要素にはlink要素を子要素として複数持つことができますので,


と定義します。class Link は以下のように定義します。


次に,author要素を定義します。
public class Author {
    /* for 
     *  
     *    Elizabeth Bennet
     *    liz@gmail.com
     *  
     */

    @Key
    public String name;

    @Key
    public String email;
}

その他に,属性と要素の内容にテキストコンテンツが与えられているtitle要素を定義します。

JavaDoc Package com.google.api.client.googleapis.xml.atom
に,
The optional value parameter of this @Key annotation specifies the XPath name to use to represent the field. For example, an XML attribute a has an XPath name of @a, an XML element <a> has an XPath name of a, and an XML text content has an XPath name of text().
とありますように,@Key("text()") と指定して,テキストコンテンツの内容を表します。

public class Title {
    /* for 
     *   This is the title of entry 1007
     */

    @Key("@type")
    public String type;

    @Key("text()")
    public String context;
}

他の要素も同様にして,上記で与えられている feed 要素を定義するデータモデル GoogleDocFeed が定義できます。


import com.google.api.client.util.Key;

public class Category {

    /*  
     *  
     */

    @Key("@scheme")
    public String scheme;

    @Key("@term")
    public String term;

}

public class Content {

    /*
     *  
     *    
This is the entry body of entry 1007
*
*/ @Key("@type") public String type; @Key("text()") public String content; } public class Link { /* * */ @Key("@rel") public String rel; @Key("@type") public String type; @Key("@href") public String href; } public class Author { /* for * * Elizabeth Bennet * liz@gmail.com * */ @Key public String name; @Key public String email; } public class Title { /* for * This is the title of entry 1007 */ @Key("@type") public String type; @Key("text()") public String context; } public class GoogleDocEntry { @Key public string id; @Key public string published; @Key public string updated; @Key public Category category; @Key public Title title; @Key public Content content; @Key("link") public List links; @Key public Author author; } public class GoogleDocFeed { @Key("gd:etag") public string gd_etag; @Key public string id; // for http://www.example.com/feed/1234.1/posts/full @Key public string updated; // for 2005-09-16T00:42:06Z @Key("link") public List links; @Key public Author author; @Key public Generator generator; @Key("openSearch:totalResults") public int totalResults; @Key("openSearch:startIndex") public int startIndex; @Key("entry") public List entries; }


今回は,具体的なコンテントをベースにしてデータモデルを定義しましたが,
schema は用意されていますので(例
Google Spreadsheets API Reference Guide (v3.0)
),それを参考にして各自でデータモデルを定義できます。


Thursday, April 07, 2011

Google Spreadsheets を Androidから扱う (4)

前回,access Token と access TokenSecretを取得しました。 これを用いて,自分のアカウントのspread sheet一覧を取得してみます。
Retrieving a list of spreadsheetsを読みますと,
https://spreadsheets.google.com/feeds/spreadsheets/private/full
に送信すれば,認証されたユーザのspreadsheetsのfeedを入手することができます。
具体的なコードは以下の通りです。

HttpTransporへの署名

String token = "your access token";
String tokenSecret = "your access tokenSecret";
HttpTransport transport = new ApacheHttpTransport();
OAuthParameters parameters = createOAuthParameters(token, tokenSecret);
parameters.signRequestsUsingAuthorizationHeader(transport);
getSpreadSheets(transport);
各メソッドの内容は以下の通りです。
createOAuthParameters
public OAuthParameters createOAuthParameters(String token, String tokenSecret) {
    OAuthParameters authorizer = new OAuthParameters();
    authorizer.consumerKey = "anonymous";
    authorizer.signer = createOAuthSigner(tokenSecret);
    authorizer.token = token;
    return authorizer;
}
createOAuthSigner
public OAuthHmacSigner createOAuthSigner(String tokenSecret) {
    OAuthHmacSigner signer = new OAuthHmacSigner();
    if (tokenSecret != null) {
        signer.tokenSharedSecret = tokenSecret;
    }
    signer.clientSharedSecret = "anonymous";
    return signer;
}
getSpreadSheet
public void getSpreadSheets(HttpTransport transport) {
    // Set AtomParser
    AtomParser parser = new AtomParser();
    XmlNamespaceDictionary dictionary = new XmlNamespaceDictionary();
    dictionary.set("", Atom.ATOM_NAMESPACE);
    dictionary.set("docs", "http://schemas.google.com/docs/2007");
    dictionary.set("batch", "http://schemas.google.com/gdata/batch");
    dictionary.set("gd", "http://schemas.google.com/g/2005");
    dictionary.set("gd:etag", "W/"DEMCQHk7eSt7ImA9WhZSGUw."");
    dictionary.set("openSearch", "http://a9.com/-/spec/opensearch/1.1/");
    dictionary.set("app", "http://www.w3.org/2007/app");
    parser.namespaceDictionary = dictionary;
    transport.addParser(parser);

    // Set Http Headers
    HttpHeaders headers = transport.defaultHeaders;
    headers.set("User-Agent", appname);
    headers.set("GData-Version", "3.0");

    HttpRequest request = transport.buildGetRequest();
    request.url = new GoogleUrl("https://spreadsheets.google.com/feeds/spreadsheets/private/full");
    try {
        HttpResponse response = request.execute();
        // null chekc していないので注意
        InputStreamReader inr = new InputStreamReader(response.getEntity().getContent()); 
        BufferedReader reader = new BufferedReader(inr, 256);
        while ((str = reader.readLine()) != null) {
            Log.d(TAG, line);
        }
        reader.close();
        inr.close();
    } catch (IOException e) {
        Log.e(TAG, e.getMessage());
        e.printStackTrace();
    }
}
これを実行し,正常にHttpResponseが得られますと,以下のようなXML documentが得られます。
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/"DEMCQHk7eSt7ImA9WhZSGUw."'>
  <id>https://spreadsheets.google.com/feeds/spreadsheets/private/full</id>
  <updated>2011-04-04T11:27:41.701Z</updated>
  <category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#spreadsheet'/>
  <title>Available Spreadsheets - Maskes(user's email address)</title>
  <link rel='alternate' type='text/html' href='http://docs.google.com'/>
  <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/spreadsheets/private/full'/>
  <link rel='self' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/spreadsheets/private/full'/>
  <openSearch:totalResults>11</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <entry gd:etag='"BBQbQxQLQit7ImBr"'>
    <id>https://spreadsheets.google.com/feeds/spreadsheets/tRsAk0wSkUi4wCBZxOJITuw</id>
    <updated>2011-04-04T04:52:59.849Z</updated>
    <category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#spreadsheet'/>
    <title>Hack For Japan Projects</title>
    <content type='application/atom+xml;type=feed' src='https://spreadsheets.google.com/feeds/worksheets/tRsAk0wSkUi4wCBZxOJITuw/private/full'/>
    <link rel='http://schemas.google.com/spreadsheets/2006#tablesfeed' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/tRsAk0wSkUi4wCBZxOJITuw/tables'/>
    <link rel='alternate' type='text/html' href='https://spreadsheets.google.com/ccc?key=0Amb6cvTCzTQRdFJzQWswd1NrVWk0d0NCWnhPSklUdXc'/>
    <link rel='self' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/spreadsheets/private/full/tRsAk0wSkUi4wCBZxOJITuw'/>
    <author>
      <name>Masked</name>
      <email>Masked</email>
    </author>
  </entry>
</feed>
次回は,得られた XML Document の parse を行います。