So-net無料ブログ作成
プログラミング ブログトップ
前の10件 | 次の10件

Nvidia Video Codec SDK7.1のNvTranscoderをいじる [プログラミング]

NVENCのお勉強の一環として、NvTranscoderをいじっている。元はH.264をH.264とかHEVCに変換するものなんだけど、実はmpeg2も大した改変もなくHEVCとかに変換できた。たぶんNVDECがサポートしているコーデックならみな対応しているんじゃないかなと思う。対応しているんだけど、入力時にH.264しか入れないようになっているので、そこを取り去ってさえすればそのまますんなりトランスエンコードされる。

具体的にはVideoDecoder.cppの114行目

if (oFormat.codec != cudaVideoCodec_H264 && oFormat.codec != cudaVideoCodec_HEVC) {
fprintf(stderr, "The sample only supports H264/HEVC input video!\n");
exit(-1);
}
というところをコメントアウトするだけでいい。ここでいらないチェックをしているから、途中で止まる。少なくとも付属しているplush1_720p_10s.m2vをHEVCにエンコードできたようだ。ただ、今までと同じようにmp4のコンテナに乗っている状態ではないので、そこは別途インプリしないといけない。とりあえずHandbrakeからソースを取ってきて組み入れてみようと思う。

ん〜mpegは結構画像が荒れるな。ブロックノイズどころの話じゃない感じ。VLCとかは細かいブレをチューニングして作られていることが分かる。VOBファイルは途中でエラーが出る。まぁそうだろうね。どちらにしてもMP4化は必須なのでやらないと。

MUX部分だけHandbrakeから持ってこようとしたけど、他のヘッダや何かがかなり入り組んでいて、それだけ抽出するわけには行かなかった。関数だけ引き出すことはできるのだろうけど、それでもHandbrake由来の型が沢山あると思うので、簡単に移植できそうにない。これはHandbrakeにTranscodeのソースを持ち込む方が楽できるかなと思ったり。それにはTranscode側の訳のわかってないところを読み込まないと。もうちっと粘度が低いと思っていたけど、Handbrake自体がかなり色々なものを取り込んでいる上に全体的にはモノリシックな構造になっている。

ってかモノシリックだと今まで思っていた。モノリシックね。lithic自体が岩石関係の言葉でmonoがついているから一枚岩的な意味らしい。日本語の読みやすさで日本語英語ができることって多いよな。シミュレーションがシュミレーションとか、あまりによくありがち。雰囲気をふいんきと読んだりするのも同じだろうなぁ。あまりに頻発するので訂正する気にもならない。まぁ意味が相手に正確に伝わればいいとは思うけど気になる人は気になるだろうな。

そんなわけでmp4boxとか組み入れるなり、外から使うなりしてちょっとやってみたい。その前にHandbrakeに突入しちゃうかもなぁ。cppファイルをそのまま使ってextern"C"して使うか、スクラッチしてC言語のNvEncで始まるAPIを素で使うか、どっちが早くて確実かなぁ。内容をはっきりと理解しなくていいのは.cppファイルのまま渡す方法なんだろうけど、それだと何だかわからないが動く状態になりかねないし、それはそれでいいかなと思う自分がいたりする。目的はHandbrakeを理解することじゃなく、NVENCを使うことなので。しかし、Handbrake久しぶりだな。ちょっとソースが懐かしいとともにQSV関係のソースが加わっていたりする。」

コメント(0) 
共通テーマ:パソコン・インターネット

Nvidia Video Codec SDK 7.1のサンプルをいじってみる [プログラミング]

Video Codec SDK 8.0は動いてくれなくて、SDK7.1を使ったら動いたという話を以前にしましたが、やっぱり全部は動いてくれそうにないという話。とそれを弄って何とかHandbrakeにつなげていきたい、という地道な作業。

とりあえずNvTranscodeやNvEncodeのサンプルはビルドできたバイナリがきちんと動くことを確かめました。出力されたバイナリもきちんと確認できたし、問題はあってもそこはインプリしていないだけという状態なのがわかって少しホッとしているところ。

エンコードはきちんとNVENCが動いてくれているのはわかったけれど、引っかかったのはNVDECの方。未だLinuxでは動いてくれていない。WindowsではDirectXでのサンプルのビルドが通りきちんと動いたのだが、Linuxと同じくOpenGLの方は動いてくれていない。というか、OpenGL用ではLinuxでは通ったビルドさえ、VisualStudioではエラーを吐いてリンクの時に転んで実行ファイルができない。Windows用のfreeglutとか入れないといけないんだろうか。そもそもWindowsには昔からOpenGLは使えたはずなんだけどな。

http://egolog.hateblo.jp/entry/2016/04/09/212608

で入れ込んだけど、static linkは対応していないとか言われたっぽい。ん〜他のfreeglutとか入れてもconflictなんとかのfreeglut_staticd.lib関係のリンクエラーが取れない。というか、Visual Studioなんだからいろいろ設定して動くようにしておいてほしいんだが…。

とにかくDirectXの方のソースは動いているので、NVDECに渡すところは使えるだろう。でも、ちょっと考えてみたんだが、NVDECってインターレースの処理とかするからGPUでデコードしてCPU側にまた戻して、という処理をしなくちゃいけなくなってしまい面倒な気がしてきた。とりあえずNVENCが使えるところを頑張ってからで後で考えればいいかと思ったのでした。それにTranscodeでh.264に関してはNVDECを使っていると思われるので、そこから掠め取ってくればMPEG2とかにも応用できそうな気はする。ただ渡すパラメーターだけの問題な気はするね、きちんとソース読んでないけど。

そんなわけで、とりあえず今できていないH.265のデータをMP4のコンテナに載せる処理をしてあげないといけない。そこいらの処理はHandbrakeの処理から取ってくる方が後々整合性が取りやすくなりそうだからパクってくる。


NVDECとCUVIDがなんか違うものかなぁと思っていたら、SDKのページにおんなじ物だよと書いてあった。SDKのページはダウンロードに行くだけで全然読んでないなぁ。

https://developer.nvidia.com/nvidia-video-codec-sdk

cuvidという名前はAPIに残ってはいるものの、今はNVDECで良いらしい。ちなみにNVENCの方はcuvid何とかで始まる関数ではなくて、NvEnc何とかという関数になって別箇になってはいる。互換性の問題だとは思うけど、統一性はないわな。別機能と考えられなくはない。

基本NVIDIAのハードウェアCODECはYUVを入出力して加工すると思うので、エンコード前のデコードもGPUでやってしまった方が効率がいいと思われる。GPUでの処理のボトルネックはグラフィックメモリへの転送にあるとは思うので、一気にデータを送ってモニョモニョした方がいいんでしょう。今見ている限りでは、データを意図的にGPUに送るとか単体の関数でやっていないみたいなんだけど、内部的にはGPUのメモリに送ったり戻したりはしているとは思うので、そこを細かくしたい場合はCUDAを使うことになるのかもしれない。

Handbrakeに入れようとすると、MPEG2とかのデータを扱うことになると思うけれども、そこいらのデコードもNVDECでもちろん出来て、そのままNVENCにYUVデータを渡せそう。HandbrakeはQSVのデコードの機能はデフォルトでオンになっていないみたいなので、その分CPUへの負荷は更に軽くなると思われる。なかなかいい感じ。というか、大体の処理がGPU内で終わらせられそうだ。ただし、MP4のコンテナに載せる処理とかはやらないと、動画がDEMUXされたようなネイキッドな状態になってしまうので、Linux以外では普通画像が再生できない。

Handbrakeはc言語で、NVENC、NVDECのサンプルはC++で書かれている。組み入れる時に面倒そうだ。NVDECもNVENCもAPIはC言語の関数になっていると思うんだけど、サンプルがC++で書かれているのは移植に面倒なんだよなぁ。extern"C"すればいいんだろうけど、API自体はC言語で書かれているので、C言語で書き直したほうが早いかもしれない。どっちが楽だろうなぁ。

C言語をC++に入れるのは問題ないとは思うんだけど、逆は気をつけないといけなさそうなのでヤダ。コンパイラも統一できそうもないし結局NVCCでやってた時とそんなに変わらないMakefileの扱いになりそうで今からウンザリ。動けば良いとは思うんだけど、元々あるソースを親子関係にあるとはいえ別の言語で書き直すとかしんどすぎるんですが。ソースそのままで無理やりがっちゃんこした方が、手を加えるのが少なくていいのかもしれない。

HandbrakeはGPUに渡す前までの前処理をすることになるわけだけども、その後のMUXの処理が上手くつながるかどうかが気になるところ。とりあえずTranscodeのソースにMPEG2とかのソースを読み込めるようにして、H.265でエンコーディングしたデータをMP4の形式にしたい。今のTranscodeだとH264しか読み込めないから、そこいらの部分をクリアにして、出力が普通のアプリでは読み込めない状態をHandbrakeのMUX部分をパクって直していく。そこからHandbrakeに組み入れられればと思う。

コメント(0) 
共通テーマ:パソコン・インターネット

nvidia video codec sdk 8.0のサンプルコードが動かない(7.1で動いた)。 [プログラミング]

NVENCを使おうとして、Video Codec SDKを入れたのは良いけれど、サンプルコードさえ動かなかった話。

https://developer.nvidia.com/nvidia-video-codec-sdk

経緯を述べておきますと現在SDKは8.0で、UbuntuだとCUDAとドライバの齟齬があってうまく動かないみたいです。仕方ないのでWindowsで動かしてみても、Ubuntuと同様にコンパイルはできるけれども、実際に動いちゃくれなかったりします。

CUDAはOptionalで入れなくてもいいのかなと思いきや、サンプルががっつりCUDAを要求しているので入れざるを得ません。WindowsではサンプルによってはDirectXで良かったりしますが、なんだかんだで使いそうなのでどちらにも入れておくことにします。

んでWindowsでもUbuntuでも出たエラー。NvTranscoderで出てくる。

Failed to find required function "cuvidGetDecoderCaps" in libnvcuvid.so
cuvidInit(0) has returned CUDA error 999

そもそもDLLとかの共有ライブラリを見に行くときにこけているのでどうしようもない。それにCUDAを入れるのは必須なのでダメだったりする。読んでいるところをコメントアウトしたものの、パラメーターからファイルを読むところでコケていて、対処のしようがなかった。

NvEncoderはエラーは出ないんだけど、出力はされていない。こういうのが一番困る。何が悪いのかわからないから、デバッガでステップ実行していかないと突き止められない。デバッグしようとしたけど何やったかは忘れた。

さんざんGT 1030 NVENC未実装問題や、デバドラがきちんと入っているかわからない問題や、CUDAやっぱ入れないとサンプル動かないやん問題を通り過ぎてきたものの、何が問題なのかわからないのでデグレードというか、SDK7.1を使ってみた。すんなり動いたw。たぶん整えた環境の問題なのだろうけど、WindowsもUbuntuも、新しいグラフィックドライバに新しいCUDAを入れたのだ。SDK8.0が悪いとしか言えない。

それに音は入っていないとは言え、Transcodeは1750fpsの爆速を叩き出していた。これは移植するモチベーション上がるなぁw。それにとりあえず動くというところが良い(喜ぶところのレベルが低いw)。まだ面倒があるのには、Windowsで生成されるファイルがmp4形式で吐き出されてないっぽいところ。でも基本的にUbuntuで開発しようとしていたから別にいいかという感じ。今回はnvccとかでコンパイルしてむりやりgccなバイナリと連結しなくても良さそうだし、きちんと動画的なお作法さえ身につけていればなんとかなりそう。

問題が一つ。Transcoderで生成したファイルが、UbuntuのVideoアプリでは見られるけど、MacやUbuntuのVLCでは見られないということ。h.265が悪いのかなと思って、H.264で出力したけど見られなかった。そもそも一般的なmp4の形式で出力できていない模様。Windowsで出力したファイルもWindowsでは見られなかった。

確かにエンコードされるファイルはbitstreamと書いてあるけれども、TranscoderくらいはきちんとMP4の形式に整形してくれないと、どういうデータが来ているのかがさっぱりわからない。ビットストリームをMP4のコンテナに乗せればいいのだろうか…(わかってないw)。MP4をdemuxした状態なのかな。しかし一般的なアプリで見られないとなると、今後は動作確認などが問題になってくるだろう。データとしてはできてはいるんだろうけど、お作法に則って出力してもらわないとねぇ。

それにしても、開発環境が動かないというのは辛いですよ、NVIDIAさん。新しい環境に問題があるというのはよくあることだとしても、過去の動いていたSDKをもっと見つけやすいところに置いておいてもらわないと、正直このレベルの完成度でリリースされるとみんな困る。

https://developer.nvidia.com/video-codec-sdk-archive

コメント(0) 
共通テーマ:パソコン・インターネット

Golangまたやっか。 [プログラミング]

SwiftをUbuntuに入れて動かしてみたんだけど、正直まだまだだという事が分かった。Deprecatedな関数が多いのにもかかわらず、まだ実装されていないものもあったりで、どこまでSwiftでできないのかが分からなかった。そもそものライブラリの性質がコマンドライン用にできていないので、Foundationを扱うのも面倒な面が多かったりする。それとXcodeみたいにSwift3になって名前が変わったものをサジェストしてくれないので、自分で調べないといけないのもお手軽に書けない理由になっているのだろう。

OSSのSwiftは待ちかなぁと思うにつけ、やっぱりGolangとかはお手軽に書けていいなぁと思ったりしている。Swiftみたいに動的スクリプト言語みたいにかっこよく書けないけれども、C/C++言語から始めた自分としては何となく安心できる言語ではある。C言語的な万能さはないけれども、C/C++の罠が極力抑えられているのがいい。というか、オブジェクト指向は使うのはいいが、ライブラリ側に近いところを作り出すと一気に面倒になる。知らなくてはいけないことが多くなるし、気を付けるところもべらぼうに増える。


車輪の再発明となるが、Golangでhttpdを作ってみたい。busyboxぐらいのシンプルさのhttpdがいい。そこからHTTP/2の実装まで手を伸ばしたい。でもまずは普通のWebサーバ。Golangは標準ライブラリにすらいろいろ材料は揃っているから、割とシンプルに書けそう。あとgoroutineを有効に使ってみたい気持ちもある。なんかそういう基本のところをやってみたくなったんだよね。今まではいかにフレームワークを使うかとかだったけど、一般的なプロトコルを実装したくなった。

通信制御系のプログラミングはしていたこともあるけれども、正直全体像が分かるほど触らせてもらえなかった。仕様書ありきの世界でもあったわけなので、正直細かいことを考えたことはなかったりした。きちんと自分がすべきタスクを果たして次に渡せばよいだけだったので、全体の動きとかはまた別の話になっていた。それにしても携帯に限っては、すでに初めのころからハードウェアで実装されて、チップを配置するなりSoCに組み込むなりするだけの世界になっているのだろうから、ソフトウェアで処理して電話の通常通信処理で電池が持たないなんてことはないんだろうね。自分が3G携帯を作っていた頃でもGSMはワンチップ化されていたっぽいしなぁ。少なくとも基地局役の機器がトランシーバー並みの大きさになっていた時は、GSMの基地局側の処理もハードウェア処理されていたんだろう。

正直ハードウェア処理というのがよく分からない。ソフトウェアほど融通が利かないという事ぐらいしかわかっていない。FPGAとかそういう世界は同僚がやっているという話は聞いたことがある程度しか知らない。プログラマブルなハードウェアというのがどういう仕組みで動くのかが想像できない。やはりCPUにメモリを積んでメモリ上にロードするという処理しかしないソフトウェア技術者としては、VHDLとかでプログラミングする世界とは違う別物として考えていた。今VHDLのソースを興味本位で見たら、ネストの深い分岐処理が多いんだなくらいで、思ったほど回路回路していない感じだった。

ソフトウェア処理している部分を、ハードウェアに落とし込むときってどうやっているんだろうなとちょっと気になったり。通信制御系だとC言語とかの奔放な書き方ができる分の冗長さがなくなってやりやすいかもしれないなと思ったりはする。何でもできるからバグができるという側面がC言語には多分にあるから、今のコンパイル言語はバグが出ないようにわりと縛りがきつくなっている。それで書きやすいかどうかはまた別の話だと思うけど。


そんなわけで、おじさんの老後の楽しみとして(笑)、Webサーバぐらいはちょうどいいボリューム感なのかもなぁと思っていたり。仕事だといちからスクラッチする事ってまずないし、かといってシステムや言語に近いところをえぐるようなことも割とあったりするから、妙な知識ばっかり蓄積する。要するにつぶしの利かない仕事が多かったというわけだ。だから仕事をセミリタイアするまでは、DBとかあんまり扱ったことがなかったりして世界の違いに戸惑ったりもした。いや、パッケージでDBを利用していたりしていたんだが、SQLそのものを発行したりするところじゃなくて、Windowsのインターフェイス部分を扱ったり、別システムとのやり取りをしたりとか、そういう雑多な周りのこまごまとしたところをよくやっていた気がする。

これがDBそのものを作るとかになると、非常に敷居が高くなってしまうのだが、通信だとそこまで専門的な知識が必要ではない。英語だけれどRFCというアクセスしやすい資料も存在することだし。他のマイナーなプロトコルのサーバ実装とかもいいかなとは思ったけれども、正直へこたれそうで比較もできないと進んでいる感がないというか、実装後の検証もしんどくなるなぁとか思ってしまう。Webサーバだったら手元のブラウザですぐに確認できる。HTTPという訳が分かっているつもりのプロトコルでも訳の分からないところとか、実際どうやっているのかわかっていないところとか、実装しないとわからないところを知ってみたいという思いがある。単に手軽なおもちゃが欲しいという気持ちがあるわけで、別にそれがプロダクトになってほしいとかそういう気持ちはほとんどない。そもそも、世の中にhttpdなんてメジャーなものがたくさんあるわけで、それを自分で作れたら面白いなと感じるだけです。

とにかく語ってないで作れや、というのが世の常だと思うので、誰でも実装できそうなところから始めます。というかviとかあんま慣れてないんだが。しかし、環境からしてviかemacsでインプリするしかないんだよな。どっちにしても特殊なキーバインドなのは否めない。やっぱりWindows上で開発していたのが長かったから、そういうのにはあまり固執していないからなぁ。お手軽な方法に逃げてしまうのが人間の性というものだ。

コメント(0) 
共通テーマ:パソコン・インターネット

SwiftをUbuntuでやる。 [プログラミング]

以下は
Ubuntu 16.04
Swift version 3.1.1
でお送りします。んがくく(古い)

インストールの大体はダウンロードサイトのページの事を大体やってある。
https://swift.org/download/#using-downloads

SwiftがOSSになって、Ubuntu上の開発環境が提供されたわけだが、Linux上での開発が良く分からない。というか、基本GUIアプリを作るためのSwiftをLinuxのコマンドラインアプリを作るための使い方とかはあんまり見ない。まぁMacがあるのにわざわざUbuntu上でやることもないのだが、なんとなく天邪鬼な自分としてはせっかくのOSSだからOSSらしく使いたい。

そもそもOSS版で使えるのは標準ライブラリとかなんだろうけど、その範囲がいまいち良く分からなかった。MacのSwiftはGUIを主眼において開発されているから、全体としてそこをどうするかの話になってきてしまう。でも、OSSなSwiftの使うところはそこじゃない。というか、そこの部分は作られてないはず。

http://quesera2.hatenablog.jp/entry/2015/12/05/163855

一年以上前の記事だけど興味深いことが書かれている。実際に実現しているところもあるのかなぁ。細かくは分からん。

Swiftの通常版とオープンソース版の違いについて、という直球な題の記事もあった。

http://qiita.com/glayash/items/a4b1b1ffef97e649395b

一言で言うなら

Foundation
libdispatch
XCTest

ということなんだろうけど、そもそもFoundationというのがどこまでなのかが分かっていない。一つ前のリンクにあるように標準ライブラリを含んだ形でFoundationがあるようだ。

実際のAppleのリファレンス的にはどこのURLに当たるのかだけれども

https://developer.apple.com/reference/swift

ここはどうにも機能的にまとまっているわけでもなく、ただのんべんだらりとアルファベット順に書かれているだけですね。

https://developer.apple.com/reference/foundation

とここにクラス群がまとまっていますが、print文はどこに属すの~という感じで、クラスのメソッドじゃない標準のものに関しては、別途挙げていかないといけないのかなと思いつつ、SwiftはGUI部分以外はほとんど何も分かっていないなと言うことが判明。いや、そんなんでOSSなSwift扱えるんか、と。

それとやたらとNSという接頭辞がObject-Cの時代を思い出させる。Swift3.0からはそれを取ろうとしているみたいだけど、正直中途半端間は否めない。

としりごんでいても仕方ないので、実際にコンパイルして動くものを作ってみようと思う。ただ単にURLを与えると、ダウンロードしてくるプログラムを作ってみる。

まず引数からURLを取ってくるところから。GUI用の言語をCUIで使うにはまずそこからだよね。

import Foundation

//print(C_ARGV)
//print(Process.arguments)
//print(Process.argv[1])
print(CommandLine.arguments)


やっと出てきた。何だよこの情報のぶれ方はw。というか、Swiftのライブラリの命名方法がやたら変わりすぎていて、いつのバージョンで効く情報なのかさえも非常に分かりづらい。

実はimport Foundationしなくても動いた。これが暗黙にFoundationをインポートするのか、なくても標準ライブラリとして装備されているのかは分からない。そもそもFoundationと標準ライブラリの境が分からんし。

NSURLはimport Foundationしないと知らないと言われた。普通に使うには基本的にFoundationをインポートしないといけないらしい。まぁ細かいパッケージをちまちまインポートするよりかずっとマシだけれども。いまだにNS何とかと書かないといけないのは新しくSwift3に移った余波としては言語に型名を近づけるのは、主要な場所以外は限定的なのかなぁ。

ダウンロードはNSURLConnectionがDeprecatedになって、NSURLSessionになったとiOS関係の記事には書いてあるのだけれども、どっちもGUIアプリ用のイベントを前提にしたものだから、普通にコマンドラインで単純に実行するには不必要と言うか、要らない機能も含まれている気がする。ソケットを生で使う程度の低レベルのものがないのかなぁと。

ともあれ非同期的な書き方をしなければいいわけで、Deprecatedになっていようが動けばとりあえず良しとする。というか、どこまで動いてくれるのかがわかっていない状態なので、別にHTTPを特に試したいわけじゃない。

NSURLConnectionがDeprecatedになったと書いてあったが、正確には多くの関数がDeprecatedになって、同期通信は出来なくなっていた。

https://developer.apple.com/reference/foundation/nsurlconnection

デリゲートとかやらないといけないのかな。面倒くさいな。URL取ってくるだけなんだけど。もっとシンプルなクラスとかないのかな。


色々なものを参考にしたんだけど、Linuxで直で動くソースが見つからないので切り張りして何とかコンパイルできるぐらいには持っていってみる。

import Foundation

print(CommandLine.arguments)
let myUrl = URL(string: CommandLine.arguments[1])!
let req = URLRequest.init(url: myUrl)
let config = URLSessionConfiguration.default

let session = URLSession(configuration: config)
let task = URLSession.shared.dataTask(with: myUrl) { data, response, error in
  do{
    try data!.write(to: URL(string: "./text.txt")!, options: NSData.WritingOptions.atomic)
  }catch{
  }
}
task.resume()


上手く動くかどうかは知らんが、コンパイルは通ったのでその点では問題ないだろう。NSのプリフィックスは軒並みコンパイラに怒られた。まぁ使わなくていいならそれでいい。

まずLLVMか何かのエラーが出るので、実行環境の./usr/libを$LD_LIBRARY_PATHに入れる。/etc/ld.conf.dの中のファイルをいじってもいいと思う。

コンパイル後動作させると、色々共有ライブラリがないといわれているみたいで、参照先がないよと言われる。

find .|grep \\.so |xargs -i% cp % .

./usr/libにパスは通っているものの、それ以下のディレクトリには通っていないので、あるもの全部を無理やりコピーしてくる。スタティックリンク用のファイルはいらないはず。

共有ライブラリを移動させた後も、libcurl.so.4がないというので入っているパッケージを入れる。

sudo apt install libcurl3

やっと動いたと思ったら、こんなメッセージが

fatal error: shared is not yet implemented: file Foundation/NSURLSession/NSURLSession.swift, line 200
Illegal instruction (core dumped)

sharedっての、インプリされてないってよw。というか、ソケット使いたいだけなので、低レベルな関数を提供してください。それかXcodeレベルに上げてください…。色々やり方はあるみたいなんだけど、簡単にしようとして逆に八方ふさがりになっている気がする。

もう少しまともになっていると思っていたんだけど、Ubuntuの開発具合はこんなもんなんだな。というか、テキストソースに互換性がないって事なのかな。あ~Macの方はObjective-Cのライブラリをはさんでいるから、直接のインプリはObj-Cって事なのかもね。なもんで、Linux版のインプリはSwiftで全部なされてないと。

Ubuntu版の中身の進捗はあまりよろしくないと言えるでしょう。時間と共に解消はされるけれども、正直何かを作るに足る状態にはなっていないのは間違いないです。だって普通にネットワークのメソッドも使えない状態なんですよ。FoundationはSwiftで書かれているって言うことは、それに近いことを自分でも出来そうな気がしますよね。Core FoundationはC言語で書かれていて、それをSwiftで呼んでいるっぽいのを読んだ気がするので、そこまでしないとまともに使えないのかもしれない。

でも、そこまでしてまで使いたい言語なのかと言うと微妙だ。楽ができるから使うとか、iOSも開発できるから使うとか、そういうカジュアルめいたものだと思っていたんだけど、どうやらそうではない感じである。やはり商業ベースのものをOSSにするというのは、それなりにハードルが高いんだなと思わざるを得ない。

あ~やっぱり本格的に手を入れようとするとCoreFoundationを使わないといけないらしい。

https://developer.apple.com/documentation/corefoundation

でも、Swiftで直接関数を提供しているみたいなので、そこいらはC言語との兼ね合いを考えなくてもいいので楽できるのかもしれない。とはいえ、そこいらへんの情報はAppleからしか出ていなくて、サンプルソースとかあんまり出ていなさそうな気がする。コピペ厨房な自分としては、全部自力でインプリするのはめんどいなぁと思うわけで。

ただ、自分でライブラリを書こうとするとCFなんちゃらの関数は使っていかないとダメだろうなという事はなんとなく分かる。ただFoundationを無視するのは結構汎用性も落ちるし、車輪の再発明になりかねない状態だったりはする。


それにソケットのところを見ると

https://developer.apple.com/documentation/corefoundation/cfsocket-rg7

#include <sys/socket.h>
とかしていて、かなりSwift使っている感が薄くなる。

ちょっとどうしようか迷っている。Swiftで書く意味があるのか、というのが一番の問題点ではある。そもそも先ほどのコンパイルだけ通したものが、Xcodeで動くのかなというのを確かめたほうがいい気がしてきた。

そして、そもそもSwiftがiOSやMacOSのGUIアプリを念頭に置いた言語であり、Foundationもそれに沿ったものであることを心に留めておかないといけない。

タグ:Swift3
コメント(0) 
共通テーマ:パソコン・インターネット

アプリ機能の拡張とか。 [プログラミング]

So-netブログが勝手に自動保存するようになった。Gmailのエディタみたいだけど、テンポラリで保存するだけで実際の記事に保存するわけじゃないっぽい。機能的には強化されてはいるもののあまり使い勝手がいいものじゃない気がした。テンポラリだからずっと前の下書きが残っていたりして、保存していない既存の記事を差し置いて復活してしまうみたいで、これではやり方によっては自分が書き足した記事が消えかねない。

一度保存してしまうと自動保存はされなくなるみたいで、なんでこんな中途半端な機能を付けるのかなぁと思ってしまう。正直、自分たちが使ってから機能をローンチしているとは思えないのだが。機能というのは間違いなく動けばいいってものではなく、そもそもの設計がきちんとしていないと便利でもなんでもないわけだ。

確かにきちんと動くというのは、プログラミングの原則から大事だとは思う。だけど、使えない機能は使わなくなるし、アラートされても無視されて最後にはうっとうしくなる。なかなか難しいとは思うけど、ツールやアプリの利用なんて部分的なものなんだよね。全部使いこなしているなんて言う人は、プログラムに使われているとしか思えないのだけれど、必要なタスクを少ない手間でやり遂げるのが一番なんじゃなかろうか。


さて、GolangもSwiftも開発環境をLXCで整えたわけだけれど、結局何を作ろうかなぁ。最近の多くが車輪の再発明にならざるを得ないから、フレームワークを使ってサービスを立ち上げるってのが今どきなんだろうなぁ。

Golangではそこそこいろんなものが作られているから、Swiftでなんかコマンドラインベースのアプリかライブラリを書きたい気がしている。それならばviでしこしこ仕事中にでも開発できるし。しかし、SwiftはOSSになる前は盛り上がっていたけれど、今はそうでもない感じがするんだがどうなんだろう。MacとかiOSの開発ではメジャーになっているのだろうけど、OSSの方はあまり芳しくない気もしなくはない。あれだけOSSにしろという要望があったのに開けてみるとこんなもんか。というか、現状はそれほど知らないんだけどね。aptのリポジトリに登録されていない時点でOSSとしては未熟と言っていいと思うんだがどうだろうか。

コメント(0) 
共通テーマ:パソコン・インターネット

Swiftをコンパイルしてみる。 [プログラミング]

https://swift.org/download/#using-downloads

Ubuntuは解凍してそこにパスを張って使うように薦めているけれど、なんかきちんとインストールディレクトリに入っていないと気持ち悪い。というか、こういう任意の場所で解凍しただけで動くものなんだ。Linuxの深いところを分かっていないので、ディレクトリの位置とか深く考えたことがない。

なんとなく一からコンパイルしたくなった。ただ気持ちの問題。というか、今ならコンテナもあるし、時間もあるしというところで。それにしてもググると他のSwiftが出てくるな。具合の悪いことに開発関係にもあったりするので、apt searchしても他のものが引っかかってくる。一瞬勘違いしそうになったじゃないかw。

https://github.com/apple/swift

ここにガッツリUbuntu用のインストール方法が出ている。最近はOSSだとみんなギフハブだな(ってもうAskaネタはいいってw)。シャブ患者はさておき、インストールしてみた。何気にUbuntu16.04はビルド通ってねぇって書いてあったりする。大丈夫なのかw?

かなり時間がかかりそうなので、途中でコンパイルを止めて、tmuxを入れて続行。LXCコンテナ内だとtmuxを動かすのに17.04用のdebファイルを入れない今のところLTSでは使えないのは前に書いたとおりで、入れ方を自分のブログを見た。まぁインストールはコピペで。にしても長い作業はtmuxとかでやっていないと色々と不安だ。

コンパイル作業を見ているとC++のソースファイルが多いみたい。SwiftはObjective-Cで書かれているわけじゃないのね。その割にはObj-Cとの互換性とかはあるみたいだけど、いちいちインターフェイスを揃えてあげないといけなくなるよなぁ。そこいらの言語の違いはWindowsで面倒だった覚えがある。でもLLVMで作られているからいくらか面倒が少なくなってはいるのかな。

案の定、コンパイルは通っているようなのですがテストが通っていないようで、インストールはされませんでした。そもそも16.10はコンパイルが通るけど、16.04ではコンパイルが通らないとか依存性の問題がバリバリ出とるとしか思えんのだが。まぁそもそもがMacのOSX上で依存性関係無しに作られていたのだろうから、すぐにUbuntuに依存性をクリアして移植と言うのは難しい話なのだろう。そもそも自分たちのXcode環境のバージョンを気にするだけで精一杯とかそのレベルであってもおかしくない。


しょうがないから16.04でビルド済みのtar玉を持ってきて解答してそこにパスを通した。まぁこれが普通なんだろうな。でも、swiftcでコンパイルした時に問題が出た。たった一行のhello worldも出力できなかったのだった。コンパイルは出来ているみたいなのだが、実行時にリンクするライブラリがないみたいで、実行環境は入れているのだが、バージョンがあっていないらしい。このコンパイラを作っている環境では問題ないのかもしれないが、普通にapt update && apt upgradeしている環境では足りないらしい。

またまたしょうがないから16.10でビルドすることにした。というか特に開発とかではLTS以外を使う気にはならないんだよなぁ。色々面倒くさい。

Testing Time: 1133.37s
Expected Passes : 2753
Expected Failures : 81
Unsupported Tests : 787
-- check-swift-linux-x86_64 finished --
--- Finished tests for swift ---

最後に出てきて、swiftコマンドを打つもインストールはされていなかった。失敗?と思いきや、テストしているんだからバイナリ自体はできているんじゃないかと思って
find . -name swiftc
とやってみると、案の定/build/Ninja-RelWithDebInfoAssert/swift-linux-x86_64/bin に出てきた。テストが失敗したのか、もともとやらないのかはわからないが、インストールまではしてくれていない。まぁコンパイル・ビルドが./configure&&make&&make installじゃない時点で気づけよという話なのかもしれないが、そこはOSS的なお作法とは違うところから来たものだから仕方ないのかもしれない。

とりあえず、print("Hello, Swift.")という中身を書いたtest.swiftを作って、./swiftc test.swiftをしたら無事コンパイルができて、./testでHello, Swift.が出てきました。そりゃ地元でコンパイルした開発環境だもんなぁ、当たり前か。たぶん16.04でもできていたので、環境を消してしまったけどもう一回16.04のコンテナでコンパイルしたものを、ディレクトリを見つけて動かして見たい。というかLTS以外の短い運命のOSでは開発などはしたくないんだヨォ。


あれ〜作られたバイナリを始めにやって見たんだけど、16.04LTSでもきちんと動くね。コンパイルをする環境を作ってから、始めから用意されたバイナリなtar玉を使おうとしたから、実行環境に問題が起こっていたんだね。どちらにしてもバイナリファイルを入れる.debファイルを作れたら作りたいなと思ったり。それにはバイナリはできているので、make installの記述ができれば大丈夫なのかなと思いつつ、makeファイルなんてしばらく書いてねぇよと独りごちる。

dpkg-buildpackageを使えばできるみたいなので、ちょっとお勉強して.debファイルを作ってみようかなぁ。なんかこのまま解凍してパスを通すってのはあまり綺麗じゃない感じがするんだけれど、そこまでの労力に見合った効果があればいいのだけれど。でも、依存性とか気にしなくて良くなったりするから、きちんとできればいいのかもね。というか、debファイルってディストリビューションのバージョンの依存性とかどうやって解消してんだろう。aptで吸収してそうだな。.debファイルがどのくらいの威力を持っているのかわかってないな。

って16.04でコンパイルするんじゃなかったのかよw。まぁ動く状況ならどんな方法でもいい。

タグ:SWIFT
コメント(0) 
共通テーマ:パソコン・インターネット

リアルで偉そうなことを言えないから、ネットで横柄になるんだろうな。 [プログラミング]

Golangで構造体のスライスのポインタについて、調べていたときの事。
構造体のスライスと言う点で二つが絡んできて面倒なのだが、良く使うパターンであることは確かだろう。構造体を単体で扱うことの方が少ない気がするし。でもそういうサンプルは少なかったりする。んで、下記で根本的に解決はした。

http://qiita.com/ruiu/items/e60aa707e16f8f6dccd8

ここを読んでわかったのは、単純な構造体はコピー渡しだけど、スライスは参照渡しになるんだねということなんだが、技術文章でこういう風に何でこんなこともわからないんだ、みたいな言い方が良くある。

私の言うことは正しいから、良くありがちなことをけなしても良いのである、みたいな知っているものの驕りを感じるんですよね。特に技術者関係に多いんだわ、昔から。初心者を平気でタコ呼ばわりする風習があって、そういうやつに限って他のことを大して知らないタコツボに入り込んでしまっていることも多い。

なんで、私は正しいことを知っていて周りは間違っている、みたいな言い方しか出来ないのか理解できない。言い方があるだろうと思うんだけど、往々にして社会不適応な人間がコンピュータ技術者に多いのは予想が付くところだ。少なくとも営業の仕事など振れない。

でも、まとまった情報として、
文字列、インターフェイス、チャネル、マップ、スライス
が始めっから参照形式の変数だ、と書いてあるというのは有用だ。本家のリファレンスに明示的にまとまっていないから、みんなが勘違いする可能性が出てきているという事だ。

ただ何度も言うように、「Goでxxxのポインタを取っているプログラムはだいたい全部間違っている」みたいに自己顕示欲プンプンな題名からわかるように、糾弾するような言い方は頭が悪い。頭が悪いと言う言葉は悪いが、知識があるが頭の良い言い回しではない、ということだ。しかし、ちょっとだけ知っていることが多いだけでどうしてこうも高慢な言い回しになるのか訳がわからない。ポインタの使い方が間違っていることがほとんどなので気をつけて、程度の表現にとどめられないこと自体がヒューマンスキルが足りていないと自分で喧伝しているようなものだ。

GoでC言語を知らずにやっていたら、あえてはまらないであろう軽微な罠なので、それほど実害があるわけでもない意味のないポインタのポインタみたいなものに目くじらを立てる意味もないと思うのだが。まぁ確かに可読性は下がるよ。でも、著しく実行速度が落ちるわけでもないから、ポインタを使えなくて問題が出るよりか随分ましな気はするんだけど。

まぁ僕としては知ることが出来てありがたかったんだけど、教えてもらっておいて文句言うな、と言う人もいると思うんだけど、世の中には表現の仕方が残念な人がこうも多いのかと言うことで。

タグ:Golang
コメント(0) 
共通テーマ:パソコン・インターネット

.bash_historyでRuby on Rails5インストール作業をプレイバック。 [プログラミング]

LXCにUbuntu16.04入れて、適当に一般ユーザー作る。そこから。


sudo apt install ruby
ruby -v


2.3とか結構新しいバージョンが入ってる。ver.2に入るころはかなり手を抜いていたのにね。面倒くさいからrbenvとか使わない。

gem -v


あ~rubygem一緒に入るっぽい。
これで一気にRailsが入ると思ったらどっこい。

sudo gem install rails

エラーが出た。

sudo apt install ruby-dev build-essential

まだ足りないらしくググって見る。nokogiriが悪いっぽいが。

sudo gem install nokogiri


コンパイルできないとか何とか

sudo apt install zlib1g-dev


Ubuntuのリポジトリサーバが死んでいるらしくファイルを取ってこれない。UbuntuのAPTサーバはたまに死んでいて、一日経つと復活していたりする。気長に待てないよなぁ。

仕方がないから他のものを入れる。

sudo apt install postgresql
sudo apt install elinks


elinksにおいてはずっと前に使ったっきりだから、Railsの動作確認に使えるかどうか良く分かってない。というか、まだRails入ってないから確かめようがない。

インストール作業ばっかりなんだから、わざわざ一般ユーザーでsudoする必要なかったなぁ。まぁ今度から環境設定のときは、コンテナのルートユーザーまんまで作業しよう。

あ~凡ミス。
sudo apt update && sudo apt upgrade

忘れてた。Ubuntuのメンテナさん疑ってごめんw。

すんなり通る。
sudo apt install zlib1g-dev


でもrailsは同じエラーを出していてもう一回build-essentialを入れたらコンパイルし始めた。なんでgcc入らんかったんやろ。

rails new hoge


上手くいくと思ったら、sudoの実行時にコケる。
sudo: no tty present and no askpass program specified

~/.bashrcに
alias sudo='sudo -S'
してあるから大丈夫だと思ったのに、他のスクリプト内だと有効じゃないみたい。なんか良く分からないな。LXCコンテナは色々と面倒。wettyだからnode.jsの設定でssh -tとか何とかしたほうが良さそうだ。
http://fishrimper.blogspot.jp/2012/09/ssh-sudo.html

shopt -s expand_aliases


やったけど上手くいかず。

http://qiita.com/narumi_/items/77002a12d62585da1fbe

やっぱり根本からやらんとあかんらしい。


でも問題となるところが違っていた。
まず、家に帰ってssh -t -t でつなぐようにWettyを設定してみたがダメでした。

/etc/sudoer に書いてみてもダメでした。
もしやと思い、家なので直でsshをつないでrails newを行っても
sudo: no tty present and no askpass program specified
が同じように出るので、sudoでrails newを動かしたらすんなり入って、前記のエラーが出なくなった。あんまりsudoで動かしたくないのだが仕方ない(メッセージで管理者権限で動かすなみたいなのが出てくるし)。


その後は、Sqlite関係のエラーが出るので、

sudo apt install sqlite3 libsqlite3-dev


あたりを入れたと思う。再度rails newで最後まで通る。
rails sで動かそうとするととexecjsあたりのエラーが出るので

sudo apt install nodejs


で解決。これで動くと思った。何か忘れている気もするが大体こんなもの。


LXCを抜けてホストOSに戻ってきたら、PostgreSQLが動いてた。ps axで普通に確認できた。コンテナでインストールされているものがデーモンとして動いてるのっていいのかな。ためしにコンテナを止めてみる。あ、Postgresも止まった。なんか良く分からないけど、コンテナで動いていてもホストOS側で見えるらしい。普通のプロセスは見えないのが普通だと思うけど、デーモンだからなのかもしれない。でも、なんか気持ち悪いな。コンテナでメモリ仕切っている意味ってあるのかな。

にしても、LXCコンテナの中でtmux使えないのな。どこかでUbuntu17.04を入れるとできるよ、みたいなことを書かれていた気がするが、debファイルででも入れられないものか。ちょっとしたところで、LXCで問題が出たりしていることも少なくないかも、気づいてないだけで。


タグ:Rails
コメント(0) 
共通テーマ:パソコン・インターネット

golangでwget -rで取りにくい画像を取りにいくものを作ったり [プログラミング]

wget -rでそのサイトを網羅的に引っこ抜く方法はほうぼうで出ていると思います。Windows10ではBash on Windowsですぐにwgetを叩けるようになっているので、サイトをもぎ取ってくるには楽チンな方法だったりします。実際、私もいろいろな方法でエロ画像をとってきたわけですが、取れないものも出てくるわけです。取れないわけじゃないんだけど、wgetでやるのは面倒なパターン。

wget -rで基本有効なのは同じサイトのHTMLや画像などになります。だからwww.hogehoge.comとかあった場合、wgetで再帰的にディレクトリを辿れても、画像がpic.hogehoge.comとかにあった場合、何も指定してあげなかったら取れないわけです。-Hオプションで他のドメインも許してあげて、-Dでその範囲のサーバを指定してあげるみたいにできるとは思いますが、pic1.hogehoge.com, pic2.hogehoge.comとか出てきたら面倒で、大体は網羅的に取れません(いきなりpic7.hogehoge.comとかでてくるかもしれないから)。

そんなわけで、ドメインが違ってもその画像だけ取ってくるものをGolangで作ってみました。とはいえ、参考のサイトのを取れただけで、みんな取れるようになったわけじゃないので、とりあえずはURLを放り込んでaタグでリンクされている画像については取れるものもあるという程度です。同じドメインにある画像も取れるようにしたかったんだけど、それはwgetでやってもらうことにして、違うドメインに貼ってあるリンクだけでも取れるようにしました。

package main

import (
    "github.com/PuerkitoBio/goquery"
    "fmt"
    "os"
    "path"
    "net/http"
    "io/ioutil"
    "strings"
    "net/url"
    "strconv"
)

func abspath(rpath string, urlstr string)(string){
  if(rpath[0] == '/'){
    u, _ := url.Parse(urlstr)
    return u.Scheme + "://" + u.Host + rpath
  }else if(strings.Contains(rpath, "http://")||strings.Contains(rpath, "https://")) {
    return rpath
  }else{
    dir, _ := path.Split(urlstr)
    return path.Join(dir, urlstr)
  }
}

func getfile( url string, dir string) {
  resp, _ := http.Get(url)
  defer resp.Body.Close()

  byteArray, _ := ioutil.ReadAll(resp.Body)
  ioutil.WriteFile("./" + dir + "/" + path.Base(url), byteArray, os.ModePerm)
}

func makedir()(string) {
    i := 0
    for ; i<10000; i++{
      _, err := os.Stat("./" + strconv.Itoa(i))
      if err == nil {
        continue
      }else{
        os.Mkdir(strconv.Itoa(i), 0777)
        break
      }
    }
    fmt.Println("mkdir:" + strconv.Itoa(i))
    return strconv.Itoa(i)
}

func main() {
    geturl := os.Args[1]
    fmt.Println(geturl)
    doc, err := goquery.NewDocument(geturl)
    if err != nil {
      fmt.Print("url scarapping failed")
      return
    }
    dirnum := makedir()
    doc.Find("a").Each(func(_ int, s *goquery.Selection) {
        dir, _ := s.Attr("href")
        if (strings.Contains(dir, ".jpg")||strings.Contains(dir,".png")||strings.Contains(dir,".gif")){
          fmt.Println(dir)
          absurl := abspath(dir, geturl)
          fmt.Println("absolute: " +absurl)
          getfile(absurl, dirnum)
        }
    })
}


もちろん適当に実験しながらだったんで、再帰的には動きません。あしからず。あとエラー処理もまともにしていません。コンパイルが通るか通らないかだけで、インデントや変数の名前とかも適当です。

使い方は$GOPATHを適当に設定して
go get github.com/PuerkitoBio/goquery
してあげて、上のソースをコンパイルするかgo runするかします。
引数に取りたいページのURLを取ってあげるだけでいいはずです。

実際動かすと、同ディレクトリに0から順番にフォルダができるので、そこに画像が格納されます。同じディレクトリでもよかったんだけど、1.jpg, 2.jpg…とかのぶち当たりそうな名前を処理するのが面倒だったので、ディレクトリを作ってそこに入れました。本人が使っての感想ですが、ちまちま取りに行かなくて済むのは楽です。ただ再帰的には動いてくれないので、サイト全部とかは無理です。本当はそこまでやりたいのだけれども、いろいろ処理を加えないといけないので、wget -rで取りにくいとわかっているところだけを取れるようにしました。

goqueryで楽できたけど、もう少し改良の余地はあるなぁと思いつつ、今回は終わり。

タグ:Golang
コメント(0) 
共通テーマ:パソコン・インターネット
前の10件 | 次の10件 プログラミング ブログトップ