diff --git a/content/blog/2017-02-17-private.md b/content/blog/2017-02-17-private.md index a726482..928f49c 100644 --- a/content/blog/2017-02-17-private.md +++ b/content/blog/2017-02-17-private.md @@ -21,7 +21,7 @@ slug = "private" どうしても重ね着がしたいという方は下のようなノースリーブがおすすめかもしれません。 -ノースリーブ : [https://www.amazon.co.jp/dp/B00RGQJSTA/](https://www.amazon.co.jp/dp/B00RGQJSTA/) +ノースリーブ : [https://www.amazon.co.jp/dp/B00RGQA/](https://www.amazon.co.jp/dp/B00RGQA/) 色は基本的に下が黒。上が白とかがいいんじゃないでしょうか。あと、Tシャツはちょっと大きめのサイズを選択すると良いと思ってます。すごく大きめのサイズのものもおすすめで家では下をはかなくて良くなりますよ(なにそれ)。 diff --git a/content/blog/2017-05-06-mac.md b/content/blog/2017-05-06-mac.md index 4e9903d..a267059 100644 --- a/content/blog/2017-05-06-mac.md +++ b/content/blog/2017-05-06-mac.md @@ -5,9 +5,9 @@ title = "sierra-jis-keyboard" slug = "mac" +++ -## KarabinerをインストールしていてSierraにアップグレードした場合、JSTキーボードがUSとして認識され、設定を変更しても再起動と同時にもとに戻ってしまう問題の解決法 +## KarabinerをインストールしていてSierraにアップグレードした場合、キーボードがUSとして認識され、設定を変更しても再起動と同時にもとに戻ってしまう問題の解決法 -- システム設定、キーボード、キーボードの種類の変更に進み、JSTに変更した後、Karabiner-Elementsをインストールして、Deviceのキーボード項目についているチェックを外す、再起動 +- システム設定、キーボード、キーボードの種類の変更に進み、に変更した後、Karabiner-Elementsをインストールして、Deviceのキーボード項目についているチェックを外す、再起動 その後、Karabiner系は全部消しても大丈夫。 diff --git a/content/blog/2017-05-18-keyboard.md b/content/blog/2017-05-18-keyboard.md index 2158b76..bfb54db 100644 --- a/content/blog/2017-05-18-keyboard.md +++ b/content/blog/2017-05-18-keyboard.md @@ -9,7 +9,7 @@ slug = "keyboard" https://github.com/syui/tsuki-layout -かな入力は今までやったことなかったし、ローマ字より速いっていうし、汎用性あるので覚えておいて損はないと思うので。また、JSTなら確認がすぐできるのもポイント高かった気がする。 +かな入力は今までやったことなかったし、ローマ字より速いっていうし、汎用性あるので覚えておいて損はないと思うので。また、なら確認がすぐできるのもポイント高かった気がする。 練習はしてないけどしてる感じです。どういうことかというと、これを書いているのは月配列で書いているのだけど、しかし、こういった実践ではなくタイピングアプリとか使ってやった方が上達早そうに思います。 diff --git a/content/blog/2017-06-08-private.md b/content/blog/2017-06-08-private.md index 9ecd99c..bed491e 100644 --- a/content/blog/2017-06-08-private.md +++ b/content/blog/2017-06-08-private.md @@ -5,7 +5,7 @@ title = "キーボードを買った" slug = "private" +++ -買ったのはlogicoolのやつ。JSTです。私は、JSTしか使ったことないのでJSTです。 +買ったのはlogicoolのやつ。です。私は、しか使ったことないのでです。 今までノートパソコンのキーボードしか使ってこなかったこともあって、やばいほど慣れません。 diff --git a/content/blog/2017-09-12-mac.md b/content/blog/2017-09-12-mac.md index f3345fb..66639ed 100644 --- a/content/blog/2017-09-12-mac.md +++ b/content/blog/2017-09-12-mac.md @@ -13,6 +13,6 @@ $ which date $ date +"%Y-%m-%d" -d "1 day" # 代わり -$ env TZ=JST-33 date +"%Y-%m-%d" +$ env TZ=-33 date +"%Y-%m-%d" ``` diff --git a/content/blog/2018-07-23-macbook-air-fix.md b/content/blog/2018-07-23-macbook-air-fix.md index 3842c4a..b578738 100644 --- a/content/blog/2018-07-23-macbook-air-fix.md +++ b/content/blog/2018-07-23-macbook-air-fix.md @@ -65,7 +65,7 @@ MacBook Airのキーボードは基本的に脆いもので、数年使用して ## 写真 -### 壊れたJST +### 壊れた ![](https://syui.gitlab.io/blog/img/post/macbook-air-keyboard-01.png) @@ -87,5 +87,5 @@ MacBook Airを分解して、組み立ててみた感想ですが、MacBook Air とは言え、正直、それほど難しい感じではないと思うので、MacBook Airが故障した人とかは、自分で直してみても面白いかもしれないなーと思います。 -そういえば、キーボードがJSTからUSになったので、USにも慣れていかないと....。 +そういえば、キーボードがからUSになったので、USにも慣れていかないと....。 diff --git a/content/blog/2019-12-09-illust.md b/content/blog/2019-12-09-illust.md index ba291c0..390627a 100644 --- a/content/blog/2019-12-09-illust.md +++ b/content/blog/2019-12-09-illust.md @@ -1,5 +1,5 @@ +++ -date = "2019-12-09T08:00:00JST" +date = "2019-12-09T08:00:00" tags = ["illust"] title = "イラスト1時間チャレンジ" slug = "illust" diff --git a/content/blog/2019-12-11-hugo.md b/content/blog/2019-12-11-hugo.md index 3934956..c6c4978 100644 --- a/content/blog/2019-12-11-hugo.md +++ b/content/blog/2019-12-11-hugo.md @@ -1,5 +1,5 @@ +++ -date = "2019-12-11T08:00:00JST" +date = "2019-12-11T08:00:00" tags = ["hugo"] title = "hugoでその日の記事がビルドされない問題を回避する" slug = "hugo" @@ -15,7 +15,7 @@ date = [":filename", ":default"] ファイルは`content/post/2019-12-09-test.md`(その日の日付)とします。 ```md:content/post/2019-12-09-test.md -date = "2019-12-09T08:00:00JST" +date = "2019-12-09T08:00:00" ``` ### hugoでその日の記事がビルドされない問題 @@ -23,9 +23,9 @@ date = "2019-12-09T08:00:00JST" これは、UTCがデフォルトになっているためだと思いますが、hugoでは、通常、`.Date.Local`を使っても、その日の記事がビルドされない問題があります。 ```html:layout/_default/list.html -{{ dateFormat "2006-01-02T15:04:05JST" .Date.Local }} +{{ dateFormat "2006-01-02T15:04:05" .Date.Local }} ``` そこで、dateをファイル名から取得する方法に切り替えると、回避できます。 -追記 : `date = "2019-12-09JST"`と書けばいける? +追記 : `date = "2019-12-09"`と書けばいける? diff --git a/content/blog/2019-12-15-trans.md b/content/blog/2019-12-15-trans.md index e4ba468..66d1d5f 100644 --- a/content/blog/2019-12-15-trans.md +++ b/content/blog/2019-12-15-trans.md @@ -1,5 +1,5 @@ +++ -date = "2019-12-15JST" +date = "2019-12-15" tags = ["gscript"] title = "Google Apps Scriptで翻訳してみた" slug = "gscript" diff --git a/content/blog/2019-12-18-xq.md b/content/blog/2019-12-18-xq.md index a463bf3..d50d5c6 100644 --- a/content/blog/2019-12-18-xq.md +++ b/content/blog/2019-12-18-xq.md @@ -1,5 +1,5 @@ +++ -date = "2019-12-18JST" +date = "2019-12-18" tags = ["xq"] title = "golangのcli toolをurfave/cli/v2に移行する" slug = "xq" diff --git a/content/blog/2019-12-22-sns.md b/content/blog/2019-12-22-sns.md index 19ecabb..336927e 100644 --- a/content/blog/2019-12-22-sns.md +++ b/content/blog/2019-12-22-sns.md @@ -1,5 +1,5 @@ +++ -date = "2019-12-22JST" +date = "2019-12-22" tags = ["heroku","sns"] title = "Herokuで立てる分散SNS" slug = "heroku-sns" diff --git a/content/blog/2019-12-23-arch.md b/content/blog/2019-12-23-arch.md index 67b214a..eb979a2 100644 --- a/content/blog/2019-12-23-arch.md +++ b/content/blog/2019-12-23-arch.md @@ -1,5 +1,5 @@ +++ -date = "2019-12-23JST" +date = "2019-12-23" tags = ["dotfiles","archlinux"] title = "Packer + Vagrant + Ansibleで構築するdotfiles" slug = "dotfiles" diff --git a/content/blog/2019-12-24-music.md b/content/blog/2019-12-24-music.md index 8df148c..cbeb39f 100644 --- a/content/blog/2019-12-24-music.md +++ b/content/blog/2019-12-24-music.md @@ -1,5 +1,5 @@ +++ -date = "2019-12-24JST" +date = "2019-12-24" tags = ["music"] title = "作曲してみた8" slug = "music" diff --git a/content/blog/2019-12-30-illust.md b/content/blog/2019-12-30-illust.md index 9bbe401..163c9ae 100644 --- a/content/blog/2019-12-30-illust.md +++ b/content/blog/2019-12-30-illust.md @@ -1,5 +1,5 @@ +++ -date = "2019-12-30JST" +date = "2019-12-30" tags = ["illust"] title = "絵を描く機会を増やしてみる" slug = "illust" diff --git a/content/blog/2020-01-17-game.md b/content/blog/2020-01-17-game.md index 074ba42..3bd822b 100644 --- a/content/blog/2020-01-17-game.md +++ b/content/blog/2020-01-17-game.md @@ -1,5 +1,5 @@ +++ -date = "2020-01-17JST" +date = "2020-01-17" tags = ["game"] title = "ゲーム2を作ってみた" slug = "game" diff --git a/content/blog/2020-01-25-dotfiles.md b/content/blog/2020-01-25-dotfiles.md index 2a05e9e..d50618c 100644 --- a/content/blog/2020-01-25-dotfiles.md +++ b/content/blog/2020-01-25-dotfiles.md @@ -1,5 +1,5 @@ +++ -date = "2020-01-25JST" +date = "2020-01-25" tags = ["dotfiles"] title = "開発環境を作り直してみる3" slug = "dotfiles" diff --git a/content/blog/2020-01-25-illust.md b/content/blog/2020-01-25-illust.md index 4dfd400..b8e3fe0 100644 --- a/content/blog/2020-01-25-illust.md +++ b/content/blog/2020-01-25-illust.md @@ -1,5 +1,5 @@ +++ -date = "2020-01-25JST" +date = "2020-01-25" tags = ["illust"] title = "イラストを描いてみた17" slug = "illust" diff --git a/content/blog/2020-01-25-pogo.md b/content/blog/2020-01-25-pogo.md index 66b625b..ece2a5b 100644 --- a/content/blog/2020-01-25-pogo.md +++ b/content/blog/2020-01-25-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-01-25JST" +date = "2020-01-25" tags = ["pokemon"] title = "ポケモンGoで最高の相棒にしてみる" slug = "pokemon" diff --git a/content/blog/2020-01-26-goodreader.md b/content/blog/2020-01-26-goodreader.md index 44c9c57..3f4dbee 100644 --- a/content/blog/2020-01-26-goodreader.md +++ b/content/blog/2020-01-26-goodreader.md @@ -1,5 +1,5 @@ +++ -date = "2020-01-26JST" +date = "2020-01-26" tags = ["ios"] title = "iosのgoodreaderでsftpのprivate-keyが読み込めない問題" slug = "goodreader" diff --git a/content/blog/2020-02-11-pogo.md b/content/blog/2020-02-11-pogo.md index 9f7dd6f..ba48ba4 100644 --- a/content/blog/2020-02-11-pogo.md +++ b/content/blog/2020-02-11-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-02-11JST" +date = "2020-02-11" tags = ["pokemon"] title = "ポケモンGoにリーグが実装されたのでやってみる6" slug = "pokemon" diff --git a/content/blog/2020-02-15-pogo.md b/content/blog/2020-02-15-pogo.md index 444b7ff..a1821e0 100644 --- a/content/blog/2020-02-15-pogo.md +++ b/content/blog/2020-02-15-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-02-15JST" +date = "2020-02-15" tags = ["pokemon"] title = "ポケモンGoにリーグが実装されたのでやってみる7" slug = "pokemon" diff --git a/content/blog/2020-02-23-private.md b/content/blog/2020-02-23-private.md index c68a01a..66ffaec 100644 --- a/content/blog/2020-02-23-private.md +++ b/content/blog/2020-02-23-private.md @@ -1,5 +1,5 @@ +++ -date = "2020-02-23JST" +date = "2020-02-23" tags = ["private"] title = "夫婦別姓について個人的な考え" slug = "private" diff --git a/content/blog/2020-03-01-pokemas.md b/content/blog/2020-03-01-pokemas.md index 74b6595..805038c 100644 --- a/content/blog/2020-03-01-pokemas.md +++ b/content/blog/2020-03-01-pokemas.md @@ -1,5 +1,5 @@ +++ -date = "2020-03-01JST" +date = "2020-03-01" tags = ["pokemon","pokemas","game"] title = "ポケマスをプレイしていて思ったこと" slug = "pokemon" diff --git a/content/blog/2020-03-15-pogo.md b/content/blog/2020-03-15-pogo.md index 7c3dec3..f222294 100644 --- a/content/blog/2020-03-15-pogo.md +++ b/content/blog/2020-03-15-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-03-15JST" +date = "2020-03-15" tags = ["pokemon"] title = "ポケモンGOバトルリーグのシーズン1が始まった" slug = "pokemon" diff --git a/content/blog/2020-03-16-pogo.md b/content/blog/2020-03-16-pogo.md index 987c4f0..1be61ec 100644 --- a/content/blog/2020-03-16-pogo.md +++ b/content/blog/2020-03-16-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-03-16JST" +date = "2020-03-16" tags = ["pokemon"] title = "ポケモンGO、バトルリーグの改善案ついて説明してみる" slug = "pokemon" diff --git a/content/blog/2020-03-24-manga.md b/content/blog/2020-03-24-manga.md index ddba383..ab8c3dc 100644 --- a/content/blog/2020-03-24-manga.md +++ b/content/blog/2020-03-24-manga.md @@ -1,5 +1,5 @@ +++ -date = "2020-03-24JST" +date = "2020-03-24" tags = ["manga"] title = "再びマンガを描きはじめた話" slug = "manga" diff --git a/content/blog/2020-03-25-vue2x.md b/content/blog/2020-03-25-vue2x.md index 626cac5..2270197 100644 --- a/content/blog/2020-03-25-vue2x.md +++ b/content/blog/2020-03-25-vue2x.md @@ -1,5 +1,5 @@ +++ -date = "2020-03-25JST" +date = "2020-03-25" tags = ["vue2x"] title = "vue 2.x + webpack 4.xでenvを使う" slug = "vue2x" diff --git a/content/blog/2020-03-28-blog.md b/content/blog/2020-03-28-blog.md index 22084d3..5304ccf 100644 --- a/content/blog/2020-03-28-blog.md +++ b/content/blog/2020-03-28-blog.md @@ -1,5 +1,5 @@ +++ -date = "2020-03-28JST" +date = "2020-03-28" tags = ["blog"] title = "ブログをはじめるならGitHub Pagesがおすすめ" slug = "blog" diff --git a/content/blog/2020-04-02-manga.md b/content/blog/2020-04-02-manga.md index 2d22721..9ea979d 100644 --- a/content/blog/2020-04-02-manga.md +++ b/content/blog/2020-04-02-manga.md @@ -1,5 +1,5 @@ +++ -date = "2020-04-02JST" +date = "2020-04-02" tags = ["manga"] title = "マンガを1話だけ完成させてみる" slug = "manga" diff --git a/content/blog/2020-04-11-vue.md b/content/blog/2020-04-11-vue.md index 677c127..7dbb45a 100644 --- a/content/blog/2020-04-11-vue.md +++ b/content/blog/2020-04-11-vue.md @@ -1,5 +1,5 @@ +++ -date = "2020-04-11JST" +date = "2020-04-11" tags = ["vue"] title = "vueのhooperでスライドを実装する" slug = "vue" diff --git a/content/blog/2020-04-12-vue.md b/content/blog/2020-04-12-vue.md index e389a36..e376f38 100644 --- a/content/blog/2020-04-12-vue.md +++ b/content/blog/2020-04-12-vue.md @@ -1,5 +1,5 @@ +++ -date = "2020-04-12JST" +date = "2020-04-12" tags = ["vue"] title = "vueでapexchartsを使いチャートを作ってみた" slug = "vue" diff --git a/content/blog/2020-04-20-ios.md b/content/blog/2020-04-20-ios.md index ac82e08..78d4089 100644 --- a/content/blog/2020-04-20-ios.md +++ b/content/blog/2020-04-20-ios.md @@ -1,5 +1,5 @@ +++ -date = "2020-04-20JST" +date = "2020-04-20" tags = ["ios"] title = "phonegapを使ってhtml5で開発したwebアプリをbuildする方法" slug = "ios" diff --git a/content/blog/2020-04-23-poke.md b/content/blog/2020-04-23-poke.md index 24eae92..c332803 100644 --- a/content/blog/2020-04-23-poke.md +++ b/content/blog/2020-04-23-poke.md @@ -1,5 +1,5 @@ +++ -date = "2020-04-23JST" +date = "2020-04-23" tags = ["pokemon"] title = "ポケモンハートゴールドをプレイしてみた" slug = "pokemon-heart-gold" diff --git a/content/blog/2020-04-25-novel-01.md b/content/blog/2020-04-25-novel-01.md index f1076a0..81ea1d9 100644 --- a/content/blog/2020-04-25-novel-01.md +++ b/content/blog/2020-04-25-novel-01.md @@ -1,5 +1,5 @@ +++ -date = "2020-04-25JST" +date = "2020-04-25" tags = ["novel"] title = "短編小説を書いてみた1" slug = "novel-01" diff --git a/content/blog/2020-04-26-novel-02.md b/content/blog/2020-04-26-novel-02.md index 8291217..68f2a93 100644 --- a/content/blog/2020-04-26-novel-02.md +++ b/content/blog/2020-04-26-novel-02.md @@ -1,5 +1,5 @@ +++ -date = "2020-04-26JST" +date = "2020-04-26" tags = ["novel"] title = "短編小説を書いてみた2" slug = "novel-02" diff --git a/content/blog/2020-04-27-novel-03.md b/content/blog/2020-04-27-novel-03.md index 23b712e..41d5d1a 100644 --- a/content/blog/2020-04-27-novel-03.md +++ b/content/blog/2020-04-27-novel-03.md @@ -1,5 +1,5 @@ +++ -date = "2020-04-27JST" +date = "2020-04-27" tags = ["novel"] title = "短編小説を書いてみた3" slug = "novel-03" diff --git a/content/blog/2020-04-29-game.md b/content/blog/2020-04-29-game.md index 61f2ad0..c0707cc 100644 --- a/content/blog/2020-04-29-game.md +++ b/content/blog/2020-04-29-game.md @@ -1,5 +1,5 @@ +++ -date = "2020-04-29JST" +date = "2020-04-29" tags = ["game"] title = "ノベルゲームの続きを作ってみた57" slug = "game" diff --git a/content/blog/2020-05-01-vocaloid.md b/content/blog/2020-05-01-vocaloid.md index 358adf4..8003eda 100644 --- a/content/blog/2020-05-01-vocaloid.md +++ b/content/blog/2020-05-01-vocaloid.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-01JST" +date = "2020-05-01" tags = ["vocaloid"] title = "作った曲を整理してみた" slug = "vocaloid" diff --git a/content/blog/2020-05-02-illust.md b/content/blog/2020-05-02-illust.md index 364dba2..51ccf54 100644 --- a/content/blog/2020-05-02-illust.md +++ b/content/blog/2020-05-02-illust.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-02JST" +date = "2020-05-02" tags = ["illust"] title = "イラストを描いてみた24" slug = "illust" diff --git a/content/blog/2020-05-03-pokemas.md b/content/blog/2020-05-03-pokemas.md index f5ea217..421ed05 100644 --- a/content/blog/2020-05-03-pokemas.md +++ b/content/blog/2020-05-03-pokemas.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-03JST" +date = "2020-05-03" tags = ["pokemon","pokemas","game"] title = "ポケマスをプレイしてみた3" slug = "pokemon" diff --git a/content/blog/2020-05-04-pokemas.md b/content/blog/2020-05-04-pokemas.md index a8d7942..1d61f03 100644 --- a/content/blog/2020-05-04-pokemas.md +++ b/content/blog/2020-05-04-pokemas.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-0 4JST" +date = "2020-05-04" tags = ["pokemon","pokemas","game"] title = "ポケマスをプレイしてみた4" slug = "pokemon" diff --git a/content/blog/2020-05-06-illust.md b/content/blog/2020-05-06-illust.md index 0192d29..47e6a7d 100644 --- a/content/blog/2020-05-06-illust.md +++ b/content/blog/2020-05-06-illust.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-06JST" +date = "2020-05-06" tags = ["illust"] title = "イラストを描いてみた25" slug = "illust" diff --git a/content/blog/2020-05-07-pokemas.md b/content/blog/2020-05-07-pokemas.md index 9906ce4..9555084 100644 --- a/content/blog/2020-05-07-pokemas.md +++ b/content/blog/2020-05-07-pokemas.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-07JST" +date = "2020-05-07" tags = ["pokemon","pokemas","game"] title = "ポケマスをプレイしてみた6" slug = "pokemon" diff --git a/content/blog/2020-05-08-illust.md b/content/blog/2020-05-08-illust.md index 7dedf4f..12c7a05 100644 --- a/content/blog/2020-05-08-illust.md +++ b/content/blog/2020-05-08-illust.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-08JST" +date = "2020-05-08" tags = ["illust"] title = "お絵かき講座、修了編" slug = "illust" diff --git a/content/blog/2020-05-08-vocaloid.md b/content/blog/2020-05-08-vocaloid.md index d30da07..db6eeda 100644 --- a/content/blog/2020-05-08-vocaloid.md +++ b/content/blog/2020-05-08-vocaloid.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-08JST" +date = "2020-05-08" tags = ["vocaloid"] title = "5曲目の修正に苦戦した話" slug = "vocaloid" diff --git a/content/blog/2020-05-10-rust.md b/content/blog/2020-05-10-rust.md index 6a7c766..ae2bf07 100644 --- a/content/blog/2020-05-10-rust.md +++ b/content/blog/2020-05-10-rust.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-10JST" +date = "2020-05-10" tags = ["rust"] title = "rustで作るcli toolに入門してみる" slug = "rust" diff --git a/content/blog/2020-05-12-rust.md b/content/blog/2020-05-12-rust.md index 904a513..6a45682 100644 --- a/content/blog/2020-05-12-rust.md +++ b/content/blog/2020-05-12-rust.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-12JST" +date = "2020-05-12" tags = ["rust"] title = "rustで作るcli tool" slug = "rust" diff --git a/content/blog/2020-05-14-pogo.md b/content/blog/2020-05-14-pogo.md index e5d963c..88d1922 100644 --- a/content/blog/2020-05-14-pogo.md +++ b/content/blog/2020-05-14-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-14JST" +date = "2020-05-14" tags = ["pokemon"] title = "ポケモンGo、最近の進捗" slug = "pokemon" diff --git a/content/blog/2020-05-15-pokemas.md b/content/blog/2020-05-15-pokemas.md index a11a919..39a898f 100644 --- a/content/blog/2020-05-15-pokemas.md +++ b/content/blog/2020-05-15-pokemas.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-15JST" +date = "2020-05-15" tags = ["pokemon","pokemas","game"] title = "ポケマスのことがわかってきたので解説してみる" slug = "pokemon" diff --git a/content/blog/2020-05-16-arch.md b/content/blog/2020-05-16-arch.md index aa6a05b..7541036 100644 --- a/content/blog/2020-05-16-arch.md +++ b/content/blog/2020-05-16-arch.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-16JST" +date = "2020-05-16" tags = ["github"] title = "pull-reqが来たときgithub-actionsを実行してhtml,sqlをreviewする" slug = "arch" diff --git a/content/blog/2020-05-17-golang.md b/content/blog/2020-05-17-golang.md index 52985ea..1cb4803 100644 --- a/content/blog/2020-05-17-golang.md +++ b/content/blog/2020-05-17-golang.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-17JST" +date = "2020-05-17" tags = ["golang"] title = "xqというcli toolにtxtをjson{body:}に出力するオプションを追加してみた" slug = "golang" @@ -9,7 +9,7 @@ shellの`cat`では、github-apiのpostでjson errorが出る場合があった ```sh $ xq j ./index.md -{"body":"+++\ndate = \"2020-05-17JST\"\ntags = [\"golang\"]\ntitle = \"\"\nslug = \"golang\"\n+++\n\n\n[xq](https://github.com/syui/xq)にtxt, mdをjsonのbodyに入れるコマンドを追加した。\n\n```sh\n$ xq j ./index.md\n```\n"} +{"body":"+++\ndate = \"2020-05-17\"\ntags = [\"golang\"]\ntitle = \"\"\nslug = \"golang\"\n+++\n\n\n[xq](https://github.com/syui/xq)にtxt, mdをjsonのbodyに入れるコマンドを追加した。\n\n```sh\n$ xq j ./index.md\n```\n"} ``` これでgh-actionsに以下のような書き方ができます。 diff --git a/content/blog/2020-05-29-illust.md b/content/blog/2020-05-29-illust.md index 137ada8..bbaf87a 100644 --- a/content/blog/2020-05-29-illust.md +++ b/content/blog/2020-05-29-illust.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-29JST" +date = "2020-05-29" tags = ["illust"] title = "お絵かき講座、応用編" slug = "illust" diff --git a/content/blog/2020-05-30-pogo.md b/content/blog/2020-05-30-pogo.md index ad709a7..6eb249f 100644 --- a/content/blog/2020-05-30-pogo.md +++ b/content/blog/2020-05-30-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-30JST" +date = "2020-05-30" tags = ["pokemon"] title = "ポケモンGo、GBLの真実" slug = "pogo" diff --git a/content/blog/2020-05-31-pogo.md b/content/blog/2020-05-31-pogo.md index eb64f00..3b91a2f 100644 --- a/content/blog/2020-05-31-pogo.md +++ b/content/blog/2020-05-31-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-05-31JST" +date = "2020-05-31" tags = ["pokemon"] title = "ポケモンGo、スポットレイトアワーなど" slug = "pogo" diff --git a/content/blog/2020-06-01-win.md b/content/blog/2020-06-01-win.md index 3bc20b4..ee1039e 100644 --- a/content/blog/2020-06-01-win.md +++ b/content/blog/2020-06-01-win.md @@ -1,5 +1,5 @@ +++ -date = "2020-06-01JST" +date = "2020-06-01" tags = ["windows"] title = "windowsの必須ツールをupdateしてみる" slug = "win" diff --git a/content/blog/2020-06-03-pogo.md b/content/blog/2020-06-03-pogo.md index 1ef9e6c..7f6866e 100644 --- a/content/blog/2020-06-03-pogo.md +++ b/content/blog/2020-06-03-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-06-03JST" +date = "2020-06-03" tags = ["pokemon"] title = "ポケモンGo、GBL S2ハイパーリーグがはじまった" slug = "pogo" diff --git a/content/blog/2020-06-06-game.md b/content/blog/2020-06-06-game.md index 52567e8..d6dbc26 100644 --- a/content/blog/2020-06-06-game.md +++ b/content/blog/2020-06-06-game.md @@ -1,5 +1,5 @@ +++ -date = "2020-06-06JST" +date = "2020-06-06" tags = ["game"] title = "ノベルゲームを更新してみた60" slug = "game" diff --git a/content/blog/2020-06-17-game.md b/content/blog/2020-06-17-game.md index 96800b0..19a4e69 100644 --- a/content/blog/2020-06-17-game.md +++ b/content/blog/2020-06-17-game.md @@ -1,5 +1,5 @@ +++ -date = "2020-06-17JST" +date = "2020-06-17" tags = ["game"] title = "ノベルゲームを更新してみた69" slug = "game" diff --git a/content/blog/2020-06-18-pogo.md b/content/blog/2020-06-18-pogo.md index ff40aaa..9bbfc28 100644 --- a/content/blog/2020-06-18-pogo.md +++ b/content/blog/2020-06-18-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-06-18JST" +date = "2020-06-18" tags = ["pokemon"] title = "ポケモンGoは早いうちからやっておいたほうがいい" slug = "pogo" diff --git a/content/blog/2020-06-19-pogo.md b/content/blog/2020-06-19-pogo.md index 75e4684..8021ebe 100644 --- a/content/blog/2020-06-19-pogo.md +++ b/content/blog/2020-06-19-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-06-19JST" +date = "2020-06-19" tags = ["pokemon"] title = "ポケモンGoのメガシンカはどうなるのか" slug = "pogo" diff --git a/content/blog/2020-06-22-illust.md b/content/blog/2020-06-22-illust.md index 2f423fc..301bb7a 100644 --- a/content/blog/2020-06-22-illust.md +++ b/content/blog/2020-06-22-illust.md @@ -1,5 +1,5 @@ +++ -date = "2020-06-22JST" +date = "2020-06-22" tags = ["illust"] title = "ヘッダー画像を変えてみた" slug = "illust" diff --git a/content/blog/2020-06-23-icon.md b/content/blog/2020-06-23-icon.md index 214288b..6284c14 100644 --- a/content/blog/2020-06-23-icon.md +++ b/content/blog/2020-06-23-icon.md @@ -1,5 +1,5 @@ +++ -date = "2020-06-23JST" +date = "2020-06-23" tags = ["icon"] title = "アイコンをいくつか作ってみた" slug = "icon" diff --git a/content/blog/2020-07-01-anime.md b/content/blog/2020-07-01-anime.md index a07baf2..f872625 100644 --- a/content/blog/2020-07-01-anime.md +++ b/content/blog/2020-07-01-anime.md @@ -1,5 +1,5 @@ +++ -date = "2020-07-01JST" +date = "2020-07-01" tags = ["anime"] title = "七星のスバルが面白かった" slug = "anime" diff --git a/content/blog/2020-07-02-pogo.md b/content/blog/2020-07-02-pogo.md index 57142c0..22b2b45 100644 --- a/content/blog/2020-07-02-pogo.md +++ b/content/blog/2020-07-02-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-07-02JST" +date = "2020-07-02" tags = ["pokemon"] title = "ポケモンGoのGBLをやめた話" slug = "pogo" diff --git a/content/blog/2020-07-03-illust.md b/content/blog/2020-07-03-illust.md index 5567211..54d8d0e 100644 --- a/content/blog/2020-07-03-illust.md +++ b/content/blog/2020-07-03-illust.md @@ -1,5 +1,5 @@ +++ -date = "2020-07-03JST" +date = "2020-07-03" tags = ["illust"] title = "新しいキャラ描いた" slug = "illust" diff --git a/content/blog/2020-07-04-curl.md b/content/blog/2020-07-04-curl.md index a0641e2..b8f5644 100644 --- a/content/blog/2020-07-04-curl.md +++ b/content/blog/2020-07-04-curl.md @@ -1,5 +1,5 @@ +++ -date = "2020-07-04JST" +date = "2020-07-04" tags = ["curl"] title = "コマンドラインからjavascriptでレンダリングされたHTMLソースを取得する方法" slug = "curl" diff --git a/content/blog/2020-07-05-vocaloid.md b/content/blog/2020-07-05-vocaloid.md index 3b13f2d..821de59 100644 --- a/content/blog/2020-07-05-vocaloid.md +++ b/content/blog/2020-07-05-vocaloid.md @@ -1,5 +1,5 @@ +++ -date = "2020-07-05JST" +date = "2020-07-05" tags = ["vocaloid"] title = "2020年上半期ボカロ曲1位の発表" slug = "vocaloid" diff --git a/content/blog/2020-07-06-game.md b/content/blog/2020-07-06-game.md index d82c03c..8e05477 100644 --- a/content/blog/2020-07-06-game.md +++ b/content/blog/2020-07-06-game.md @@ -1,5 +1,5 @@ +++ -date = "2020-07-06JST" +date = "2020-07-06" tags = ["game"] title = "ノベルゲームの週刊連載はじめました" slug = "game" diff --git a/content/blog/2020-07-08-pogo.md b/content/blog/2020-07-08-pogo.md index 6e2eabd..83dd497 100644 --- a/content/blog/2020-07-08-pogo.md +++ b/content/blog/2020-07-08-pogo.md @@ -1,5 +1,5 @@ +++ -date = "2020-07-08JST" +date = "2020-07-08" tags = ["pokemon"] title = "ポケモンGo、4周年" slug = "pogo" diff --git a/content/blog/2020-07-19-illust.md b/content/blog/2020-07-19-illust.md index 32411d7..40195a2 100644 --- a/content/blog/2020-07-19-illust.md +++ b/content/blog/2020-07-19-illust.md @@ -1,5 +1,5 @@ +++ -date = "2020-07-19JST" +date = "2020-07-19" tags = ["illust"] title = "イラスト描いてみた29" slug = "illust" diff --git a/content/blog/2020-07-21-illust.md b/content/blog/2020-07-21-illust.md index 6ced501..fbf6ae8 100644 --- a/content/blog/2020-07-21-illust.md +++ b/content/blog/2020-07-21-illust.md @@ -1,5 +1,5 @@ +++ -date = "2020-07-21JST" +date = "2020-07-21" tags = ["illust"] title = "イラストを修正してみた" slug = "illust" diff --git a/content/blog/2024-08-10-ip.md b/content/blog/2024-08-10-ip.md index fb9d2e8..4fb3578 100644 --- a/content/blog/2024-08-10-ip.md +++ b/content/blog/2024-08-10-ip.md @@ -37,5 +37,5 @@ $ curl -sL ipinfo.io どうやらicloud private relayのipv4はcloudflareを使ってるみたいです。 -最近、icloud private relayが使いやすいのでbrowserをsafariに置き換えようかなと思っています。もうすぐchromeの広告ブロック排除がくるみたいだし。 +最近、icloud private relayが使いやすいのでbrowser(mac)をsafariに置き換えようかなと思っています。もうすぐchromeの広告ブロック排除がくるみたいだし。 diff --git a/content/blog/2024-08-11-safari.md b/content/blog/2024-08-11-safari.md new file mode 100644 index 0000000..c159697 --- /dev/null +++ b/content/blog/2024-08-11-safari.md @@ -0,0 +1,39 @@ ++++ +date = "2024-08-11" +tags = ["mac"] +title = "macのbrowserをsafariにした" ++++ + +chromeからsafariに切り替えました。 + +理由としては、以下の4つです。 + +1. ios(mobile)で使っているのがsafariなので統一したかった +2. safariだとicloud private relayが使える +3. chromeだとprivate windowでもcacheが効いて開発に支障が出る +4. chromeがadblockなどを排除予定 + +### chromeだと最新のpreviewができない + +主にweb開発ですがchromeだと最新のsrc previewが反映されません。cookieかcacheかわかりませんが、それが残っているのだと思います。 + +safariだとprivate windowは普通に機能します。localhostでpreviewするときも支障がありません。 + +ちなみに、chromeのprivate windowは完全にprivateではありません。 + +### google翻訳やgoogle検索を使わなくなった + +これまでchromeを使っていた理由は`google翻訳`があるからです。 + +私はbrowserをあまりカスタマイズせず、拡張機能も入れず、ほとんどの初期機能を無効にし、基本設定のまま使います。ですからchromeについているgoogle翻訳は便利でした。 + +しかし、近年、`chatgpt`, `perplexity.ai`などのほうがよく使うようになり、逆にgoogle検索やgoogle翻訳をあまり使わないようになっていました。 + +これだとchromeを使うメリットは薄れ、デメリットが目立ちます。 + +### icloud private relayが使える + +ほとんどのアプリはicloud relayが有効になっていますが、browserはsafariくらいしか通しません。 + +もともとスマホはsafariしか使いませんし、パソコンも統一したほうがいいだろうということで、しばらくsafariを使ってみることにします。 + diff --git a/content/blog/2024-08-15-vtuber.md b/content/blog/2024-08-15-vtuber.md new file mode 100644 index 0000000..4f7ed8e --- /dev/null +++ b/content/blog/2024-08-15-vtuber.md @@ -0,0 +1,107 @@ ++++ +date = "2024-08-15" +tags = ["vtuber", "fuwamoco"] +title = "vtuberのfuwamocoを見始めた" ++++ + +数日前からvtuberを見はじめて、最初はさくらみこを見て「へえこんな人がいるのか面白い」と思って、次に古石ビジューを見て、そこからふわもこ(fuwamoco)を見てる。 + +今回はそこで考えた色々なことを話していきたい。 + +### fuwamocoのすごさ + +私はfuwawaが特に気に入ってて、好き。fuwawaが怒ってるところは見たことないし、想像つかないところがいい。 + +なんだけど、今回は主に技術的な側面からfuwamocoを考察します。 + +fuwamocoを見てて思ったのは、この子達はプロだなってこと。あらゆる面でそのことを読み取れます。 + +例えば、彼女たちの口癖であるbaubauです。繰り返されることで定着して、今やbaubauって聞くと「あ、fuwamocoだ」ってわかる。 + +彼女たちはおそらくいくつかの決め事があり、それを実行していると思う。しかも日々配信がどうすれば面白くなるか考えてupdateしていく姿勢もある。 + +この両方を持ち合わせることは難しい。例えば、jpは精神論や昔ながらのやり方を重要視する傾向にあるように感じたのに対し、enのfuwamocoは決まりを大切にしながらも、updateを大切にしているように感じた。とはいえ精神論が重要じゃないわけじゃない。最後まで立ってるやつが勝ちみたいな考えは好き。 + +また、fuwamocoが特徴的なのが二人組みであること。 + +私は最初はソロでやっている人を見てるんだけど、最終的には二人組でやっている人を見るようになる。 + +なぜかというと、多分、飽きるからだと思う。二人組の場合、やり取りの幅は広い。 + +そして、vtuberを見ていて最も楽しいと感じるのがadventでやっているとき。adventというのはfuwamocoの同期の人達が集まってわちゃわちゃやってることがあって、それが一番おもしろいと思う。 + +2番目がfuwamocoで3番目がソロのメンバーという感じ。 + +やっぱり二人組が強いと思う。お笑いも最終的には二人組に行き着く事が多い。 + +次にすごいのはfuwamocoがオタクであるということ。そして、ただのオタクじゃないことはわかる。 + +その他にもネーミングの凄さやfuwamoco morning、冒頭の「ふわわじゃないよ、もここだよ」、オープニングのセンスの良さ、鳥のマスコットなどなどすごいところはたくさんあるけど、一番はやっぱり視聴者が嫌な気分になることがないってところ。見ていて楽しいところ。 + +配信ってどうしても我が出てしまって、それはいいことでもあるんだけど、悪いことでもあると思う。 + +特に悪いのは個人的資質(性格の悪さ)による我が出ること。そのへんは内面がいい人を選ぶしかない。 + +vtuberに内面なんてあるのと思われるかもしれないけど、毎日配信だから個人的な性質は隠しきれない。 + +だからそういうのは必ず出ると思ったほうがいい。 + +おそらく、fuwamocoは個人的資質が良いこと(性格が良いこと)と、いくつかの決め事でプロに徹すること。この2点がすごいと思った。 + +ちなみに、みこちゃんもbibooも好きだしかわいい。 + +### vtuberをおすすめしない + +こういうのを見て、やってみたいなあって思う。でもそういうのはおすすめしない。 + +理由としては、何かが流行っているとき、先行者利益はすでに失われている。 + +vtuberになるには、vtuberがまだ知られていないし、誰もやっていない、流行ってもいない。そういうとき勇気を出してやるのが一番いい。 + +逆に言うと、そこで勇気を出し努力をしてきた人たちが最もvtuberで活躍すると思う。それ以外は厳しいと思う。 + +「誰でもvtuberになれます」、「今、vtuberが大流行」みたいな状況でそういうのに参入するのはおすすめしない。 + +個人的には誰もやってないこと、かつ自分が好きで続けられて得意なことをやるのが良いように思います。 + +### vtuberの技術が気になったのでやってみた + +実はvtuberにハマってから数日、自分ならどういった形で実現できそうかやってみました。 + +途中でモーションキャプチャに切り替えて動かしてます。 + + + +vみたいなことやるならアイのモデルを貸してもらうしかないな。名前はyoutubeで@syuiが取れなかったので@syaiなんだけどこれになる。シャイ?かな。んでその際はアイじゃなく自分(シャイ)であることを説明しないと。作者とキャラって全く関係ない別人だから。 + +ただ、やるにしてもvtuberでは厳しいと思う。何かを新しいものを組み合わせないとダメそう。 + +みんなを楽しませるもので、かつ気軽に楽しめるもので、今までにないもの。 + +どういった形で実現できそうかな。 + +### ゲーム動画の注釈 + +今回実装したもの + +#### room(home) + +vではみんな背景にroomを表示しているので作ることにした。 + +twinmotion+collisionで実装してる。meshを全選択して、右クリックで`アセットアクション -> プロパティマトリクスで選択内容を... -> collision complexity(use complex collision as simple...)`を選択します。 + +#### motion caps + +モーションキャプチャ + +vrmvmc+abpの切り替えで実装してる。blueprintはこんな感じ。 + +```sh +cast to CBP_SandboxCharacter_ai -> target:ai, target:sk_ai -> set anim instance class -> ABP_GenericRetarget_2 +``` + +#### loading screen + +ローディング画面 + +バグあり、build後に一時背景が映り込んでしまう。editor上では再現しないし、コード的には映り込まないはず。 diff --git a/content/blog/2024-08-24-ue.md b/content/blog/2024-08-24-ue.md new file mode 100644 index 0000000..0ef9020 --- /dev/null +++ b/content/blog/2024-08-24-ue.md @@ -0,0 +1,14 @@ ++++ +date = "2024-08-24" +tags = ["ue","ue5"] +title = "gpt-4o-miniに乗り換え" ++++ + +この前、[elevenlabs](https://elevenlabs.io/)を使って、ゲーム内で音声で聞くと音声で返してくれるようにした。 + +その時、`gpt-3.5-turbo`より`gpt-4o-mini`のほうが安いことに気づいたので乗り換えた。 + +https://openai.com/index/gpt-4o-mini-advancing-cost-efficient-intelligence/ + +ただ、elevenlabsは、かわいい声が少なかったのと、日本語の発音がちょっと微妙なことがあるので、これよりおすすめのものはないかなと思ってる。 + diff --git a/content/blog/2024-08-28-three.md b/content/blog/2024-08-28-three.md new file mode 100644 index 0000000..104f526 --- /dev/null +++ b/content/blog/2024-08-28-three.md @@ -0,0 +1,98 @@ ++++ +date = "2024-08-28" +tags = ["vrm","three"] +title = "theatre.jsを使ってみる" ++++ + +three.jsをGUIで調整するためのlibです。reactのexampleがあるのでreactで書きます。 + +ちなみに、最近は色々なprojectがreactばかりになってきたのでreactを使っています。ただ、vueのほうがわかりやすいのでvueをおすすめしておきます。jsに近いほどよいですね。最初はjs+html+cssが一番ですけど。 + +```sh +$ nvm use 21 + +# https://www.theatrejs.com/docs/latest/getting-started/with-react-three-fiber +$ npx create-react-app theatre --template typescript +$ npm install --save react three @react-three/fiber @theatre/core @theatre/studio @theatre/r3f +$ npm install --save-dev @types/three +``` + +```json:package.json +{ + "name": "vite-react-typescript-starter", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@theatre/core": "^0.6.1", + "@theatre/r3f": "^0.7.2", + "@theatre/studio": "^0.6.1", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@eslint/js": "^9.9.1", + "@types/react": "^18.3.4", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "eslint": "^9.9.1", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.11", + "globals": "^15.9.0", + "typescript": "^5.5.3", + "typescript-eslint": "^8.3.0", + "vite": "^5.4.2" + } +} +``` + +```ts:src/main.tsx +import './index.css' +import { createRoot } from 'react-dom/client' +import React, { useEffect } from 'react' +import { Canvas } from '@react-three/fiber' +import studio from '@theatre/studio' +import extension from '@theatre/r3f/dist/extension' +import { SheetProvider, editable as e, PerspectiveCamera } from '@theatre/r3f' +import { getProject } from '@theatre/core' +import demoProjectState from './state.json' + +studio.initialize() +studio.extend(extension) + +//const demoSheet = getProject('Demo Project', { state: demoProjectState }).sheet('Demo Sheet') +const demoSheet = getProject('Demo Project').sheet('Demo Sheet') +const App = () => { + useEffect(() => { + demoSheet.project.ready.then(() => demoSheet.sequence.play({ iterationCount: Infinity, range: [0, 1] })) + }, []) + + return ( + + + + + + + + + + + + ) +} + +createRoot(document.getElementById('root')!).render() +``` + +```sh +$ npm run dev +``` + +https://github.com/AndrewPrifer/CodropsCameraFlyThroughTutorial/ diff --git a/content/blog/2024-09-01-voice.md b/content/blog/2024-09-01-voice.md new file mode 100644 index 0000000..2c54ffb --- /dev/null +++ b/content/blog/2024-09-01-voice.md @@ -0,0 +1,145 @@ ++++ +date = "2024-09-01" +tags = ["mac","ue", "obs"] +title = "obs+discord+beatriceを使う" ++++ + +obsは配信のためのアプリですが、windowsで使えるマイクがないので、iphoneかmacを使って音声変換してdiscordから取ってみた。このやり方がすごく良かった。あと後述する[ちやは神社](https://chihaya369.booth.pm/)が配布しているrvc modelがすごかった。 + +- https://github.com/w-okada/voice-changer +- https://huggingface.co/wok000/vcclient000/tree/main + +```sh +./start_http.command +``` + +- https://booth.pm/ja/items/4701666 + +まずマイクに近づかないと音を取れないのがきつい。なので離れていても音を取るのがいい。最初はiphone(discord)からwindowsに繋いだらかなり離れててもしっかりと音を取れてよかった。 + +ただ、音声変換があまりうまくいかなくて、obsのVST Pluginだったかを使うのは厳しいと感じた。なので、方向を変えてmac(discord)から接続することにした。 + +macのgaragebandによる音声変換も使えるけど、beatriceがいいらしいのでw-okada/voice-changerから使うことにした。 + +## webcam motion capture + +- https://webcammotioncapture.info/ja/ + +まずvrm4u(vmc)ではwebcam motion captureが動きません。ue5.4.4のvrm4u(202408)の環境ですが動かない。しかし、一旦、vseefaceなどを挟むと使用できます。ただし、`webcam motion capture`と`w-okada/voice-changer`を同時に使用するとアプリが落ちます。時間経過でwebcamのcaptureが動かなくなります。 + +## discordを使う理由 + +discordからでないと音量が大きくなりません。小さい声でもちゃんと拾って変換してくれるやり方として、discordを使うとうまくいきました。ただし、高価なマイクがある場合はそちらの方が良いでしょう。 + +## 配信環境 + +[mac] +1. VB-Cableで仮想オーディオデバイス(output)を起動 +2. discordのinputに指定 +3. w-okada/voice-changerを起動してoutputにいれる + +[windows] + +4. discordでボイスチャットに入る(別アカウント)、ここで音声が聴こえるはず +5. obsでdiscordの音声キャプチャ +6. webcam motion capture -> vseefaceでカメラからvrmを動かせるようにする +7. ue5を起動して、obsでウィンドウキャプチャ。youtubeアカウントに接続し、配信管理から予約、開始する。開始したあとは準備できるまで音声キャプチャをミュート。ゲームを調整できれば開始してミュートを切る + +配信中にやること。操作がちょっと大変です。カメラ操作や移動操作など。 + +また、英語音声に変換しながら配信する予定。自動音声変換は精度が悪かったので文字列にしました。文字を打ち込むかあらかじめ用意しておいた文字を変換します。これをmacで流すとdiscordを通じてかなりはっきり英語を喋ってくれます。たまってきたら音声ファイルをpecoとかfzfで検索できるようにしておくと良さそう。 + +```sh:voice.zsh +#!/bin/zsh + +d=${0:a:h} +f=$d/voice.json +vdir=$d/voice_dir +cfg=~/.config/ai/voice.json + +if [ ! -d $vdir ];then + mkdir -p $vdir +fi + +if [ -z "$1" ];then + ep=`cat $f|jq length` + ep=$((ep - 1)) +else + ep=$1 +fi + +j=`cat $f|jq ".[$ep].body"` +n=`echo $j|jq length` +n=$((n - 1)) + +fnction voice_chat() { + #echo chat : https://openai.com + #echo voice : https://elevenlabs.io + + vfile=$vdir/${ep}_${i}.mp3 + if [ -f $vfile ];then + mpv $vfile + echo voice ok + read + continue + fi + + echo "[$i]" + t=`echo $j|jq -r ".[$i].text"` + echo $t + echo --- + read chat_text + if [ -z "$chat_text" ] && [ -n "$t" ];then + chat_text=$t + fi + echo $chat_text + echo --- + + chat_api=`cat $cfg|jq -r .chat_api` + voice_text=`curl -sL https://api.openai.com/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer $chat_api" -d "{ \"model\": \"gpt-4o-mini\", \"messages\": [{\"role\": \"user\", \"content\": \"次の文章を英語に訳して\n\n$chat_text\"}], \"temperature\": 0.7 }"|jq ".choices.[].message.content"` + + echo $voice_text + # like-model + voice_id=zrHiDhphv9ZnVXBqCLjz + # alice-model + voice_id=Xb7hH8MSUJpSbSDYk0k2 + voice_api=`cat $cfg|jq -r .voice_api` + curl -sL --request POST \ + --url https://api.elevenlabs.io/v1/text-to-speech/$voice_id \ + --header "xi-api-key: $voice_api" \ + --header 'Content-Type: application/json' \ + --data "{ + \"text\": $voice_text, + \"model_id\": \"eleven_multilingual_v2\", + \"voice_settings\": { + \"stability\": 0.5, + \"similarity_boost\": 0.5 + } + }" --output $vfile && mpv $vfile +} + +for ((i=0;i<=$n;i++)) +do + voice_chat +done +``` + +```sh:voice.json +[ + { + "id":1, + "body" :[ + { "text":"こんにちは、みんな"}, + { "text":"配信を見てくれてありがとう。またね。"} + ] + } +] +``` + +### なぜue5(editor)で起動するのか? + +editorは相当重いので本来はbuildしたpackageで実行する方が良いです。しかし、buildするとvrm4u(vmc)の表情が動かなくなります。またstandaloneはもっと重くなりますので選択しません。PIEでwindowを作りません。windowを作ると新しい問題が発生しますし、動作も重くなります。 + +## rvc model + +boothでいくつかrvc modelを販売しているけどおすすめしません。freeのものも含めて使用できるレベルのものは現状少ないと感じています。 diff --git a/content/blog/2024-09-02-ws-sixel.md b/content/blog/2024-09-02-ws-sixel.md new file mode 100644 index 0000000..721cde8 --- /dev/null +++ b/content/blog/2024-09-02-ws-sixel.md @@ -0,0 +1,37 @@ ++++ +date = "2024-09-02" +tags = ["windows"] +title = "windows terminalでsixelを使う" ++++ + +現時点ではwindows terminalの`preview 1.22`で使用できるようになりました。 + +https://github.com/microsoft/terminal/releases + +![](/img/windows_terminal_sixel.png) + +最も手っ取り早くlibsixelをbuildする方法はmsys2を使うことです。 + +```sh +$ scoop install msys2 +# ここでmsys2を起動 +$ msys2 + +$ pacman -S git make gcc +$ git clone https://github.com/saitoha/libsixel +$ cd libsixel +$ ./configure +$ make +$ make install + +$ ls ./converters/img2sixel.exe +$ which img2sixel.exe + +# 画像を表示 +$ img2sixel.exe syui.png + +$ exit +``` + +ref : https://devblogs.microsoft.com/commandline/windows-terminal-preview-1-22-release/ + diff --git a/content/blog/2024-10-01-holo.md b/content/blog/2024-10-01-holo.md new file mode 100644 index 0000000..14c40db --- /dev/null +++ b/content/blog/2024-10-01-holo.md @@ -0,0 +1,222 @@ ++++ +date = "2024-10-01" +tags = ["vrm"] +title = "3Dホログラムを作った" ++++ + +この前、ホログラムを作ってみようと思い10分くらいで作ってみた。必要なものは透明板だけ。それを斜めに設置してスマホで黒背景の3Dモデルを表示する。 + +もともと写真立てが余っててそれに付いてる透明板を使った。 + +設置にはスマホの箱が便利だった。どちらかに切り込みを入れればいいと思う。 + +ここまではっきり映るとは思ってなくて驚いた。余ってるスマホを何に使おうと思ってたので、こういうのを表示させておくといいかも。ただし、表記は反転させないといけないみたい。 + + + +## react + tsx + three-vrm + +一応、最小限のコードを載せておきます。反転は対応しています。 + +```json:package.json +{ + "name": "holoai", + "version": "0.1.0", + "private": true, + "dependencies": { + "@pixiv/three-vrm": "^3.1.1", + "@pixiv/three-vrm-animation": "^3.1.1", + "@react-three/drei": "^9.114.0", + "@react-three/fiber": "^8.17.9", + "@react-three/postprocessing": "^2.16.3", + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.5.2", + "@types/node": "^16.18.112", + "@types/react": "^18.3.10", + "@types/react-dom": "^18.3.0", + "@types/three": "^0.167.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-scripts": "5.0.1", + "three": "^0.167.1", + "three-stdlib": "^2.30.5", + "typescript": "^4.9.5", + "web-vitals": "^2.1.4" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} +``` + +```css:src/index.css +.time { + transform:scale(-1,1); + position: absolute; + top: 10px; + padding: 10px; + z-index: 100; + color: #e9ff00; + font-size: 30px; + text-align: center; +} +``` + +```ts:src/pages/time.tsx +import React, { useState, useEffect } from 'react'; + +//function reverseString(str: string): string { +// return str.split('').reverse().join(''); +//} + +const ScreenTimeCanvas: React.FC = () => { + const [currentDateTime, setCurrentDateTime] = useState(''); + //const [reversedDateTime, setReversedDateTime] = useState(''); + + useEffect(() => { + const updateDateTime = () => { + const now = new Date(); + const formatted = now.toLocaleString("ja-JP", { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }); + setCurrentDateTime(formatted); + //setReversedDateTime(reverseString(formatted)); + }; + updateDateTime(); + const timer = setInterval(updateDateTime, 1000); + return () => clearInterval(timer); + }, []); + + return ( +
+

{currentDateTime}

+
+ ); +}; + +export default ScreenTimeCanvas; +``` + +```ts:src/pages/vrm.tsx +import * as THREE from 'three' +import React, { useState, useEffect, useRef } from 'react'; +import { OrbitControls } from '@react-three/drei' +import { useFrame, Canvas } from '@react-three/fiber'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import { VRM, VRMUtils, VRMLoaderPlugin } from '@pixiv/three-vrm'; +import { VRMAnimationLoaderPlugin, VRMAnimation, createVRMAnimationClip } from "@pixiv/three-vrm-animation"; + +interface ModelProps { + url: string + url_anim: string + scale: [number, number, number] + position: [number, number, number] + rotation: [number, number, number] +} + +const VRMModel: React.FC = ({ url, url_anim, position, rotation, scale }) => { + + const [vrm, setVrm] = useState(null); + const mixerRef = useRef(null); + + useEffect(() => { + const loader = new GLTFLoader(); + loader.register((parser) => new VRMLoaderPlugin(parser)); + loader.register((parser) => new VRMAnimationLoaderPlugin(parser)); + loader.load(url, (gltf) => { + const vrmModel = gltf.userData.vrm as VRM; + VRMUtils.removeUnnecessaryJoints(vrmModel.scene); + setVrm(vrmModel); + const mixer = new THREE.AnimationMixer(vrmModel.scene); + mixerRef.current = mixer; + loader.load(url_anim, (animGltf) => { + const vrmAnimations = animGltf.userData.vrmAnimations as VRMAnimation[]; + if (vrmAnimations && vrmAnimations.length > 0) { + const clip = createVRMAnimationClip(vrmAnimations[0], vrmModel); + mixer.clipAction(clip).play(); + } + }); + }); + }, [url, url_anim]); + + useFrame((state, delta) => { + if (mixerRef.current) mixerRef.current.update(delta); + if (vrm) vrm.update(delta); + }); + + return vrm ? : null; +}; + +export const VRMModelCanvas = () => { + return ( +
+ + {/* Light gray background */} + + + + + +
+ ) +} +export default VRMModelCanvas; +``` + +```ts:src/App.tsx +import React from 'react' +import VRMModelCanvas from './pages/vrm' +import ScreenTimeCanvas from './pages/time' + +const App = () => { + return ( + <> + + + + ) +} + +export default App; +``` diff --git a/content/blog/2024-10-02-vrm4u.md b/content/blog/2024-10-02-vrm4u.md new file mode 100644 index 0000000..a0da4d1 --- /dev/null +++ b/content/blog/2024-10-02-vrm4u.md @@ -0,0 +1,192 @@ ++++ +date = "2024-10-02" +lastmod = "2024-10-03" +tags = ["vrm","ue"] +title = "ue5.5と最新のvmc事情" ++++ + +unreal engine 5.5.0 preview(ue5.5p)がインストールできるようになっています。今回は最新環境のvmc事情を解説します。 + +## vmcとは + +webカメラから表情や動きをキャラクターに反映させるためのものです。vmcはprotocolとclientがあります。大抵はprotocolを指します。webカメラからの読み取りをcaptureといいます。つまり、captureとprotocolとclientを組みわせて動作します。ueで使うには更にvmcを受信してキャラクターに反映させるpluginが必要です。わけがわからないと思いますが、そんな感じです。 + +- https://github.com/sh-akira/VirtualMotionCapture +- https://github.com/ruyo/VRM4U +- https://github.com/HAL9HARUKU/VMC4UE +- https://github.com/HAL9HARUKU/ueOSC +- https://github.com/HAL9HARUKU/VRMMapExporter +- https://github.com/vrm-c/UniVRM + +## vmc4ueをue5.5でbuildしてみよう + +> この手順は興味がある人以外は読み飛ばすことを推奨します。表情を動かしたい人はこの方法で問題を解決することができません。 + +`vmc4ue`はue5.1までしかbuildされていません。そこでue5.5でbuildして使えるようにしてみます。 + +まずc++でprojectを作成し、patchをsrcに当てて`$project/Plugins/`に入れます。projectをueで開くとbuildされます。正常に終了するとeditorが開きます。 + +> c++で作成したprojectには$project.slnが作成されますので、それを開いてrebuildしてもいいです。 + +なお、patchはbuildが通るよう適当に作ったものです。vmcは動きますが、表情は動きませんでした。 + +```cpp:VMC4UEBlueprintFunctionLibrary.cpp.patch +--- ./VMC4UE/VMC4UE/Source/VMC4UE/Source/VMC4UEBlueprintFunctionLibrary.cpp ++++ ./VMC4UEBlueprintFunctionLibrary.cpp +@@ -119,27 +119,29 @@ UVMC4UEStreamingSkeletalMeshTransform* UVMC4UEBlueprin + { + return nullptr; + } +- ++ ++ UVMC4UEStreamingSkeletalMeshTransform* StreamingSkeletalMeshTransform = nullptr; ++ ++ // Try to get existing transform + { +- // Get + FRWScopeLock RWScopeLock(OSCManager->RWLock, FRWScopeLockType::SLT_ReadOnly); +- auto StreamingSkeletalMeshTransform = OSCManager->StreamingSkeletalMeshTransformMap.Find(Port); +- if (StreamingSkeletalMeshTransform != nullptr) ++ auto FoundTransform = OSCManager->StreamingSkeletalMeshTransformMap.Find(Port); ++ if (FoundTransform != nullptr) + { +- return *StreamingSkeletalMeshTransform; ++ return *FoundTransform; + } + } ++ ++ // Create new transform if not found + { +- // Create + FRWScopeLock RWScopeLock(OSCManager->RWLock, FRWScopeLockType::SLT_Write); +- auto StreamingSkeletalMeshTransform = OSCManager->StreamingSkeletalMeshTransformMap.Find(Port); +- if (StreamingSkeletalMeshTransform != nullptr) ++ auto FoundTransform = OSCManager->StreamingSkeletalMeshTransformMap.Find(Port); ++ if (FoundTransform != nullptr) + { +- return *StreamingSkeletalMeshTransform; ++ return *FoundTransform; + } +- UVMC4UEStreamingSkeletalMeshTransform* NewStreamingSkeletalMeshTransform = NewObject(); + +- //FRWScopeLock RWScopeLock2(NewStreamingSkeletalMeshTransform->RWLock, FRWScopeLockType::SLT_Write); ++ UVMC4UEStreamingSkeletalMeshTransform* NewStreamingSkeletalMeshTransform = NewObject(); + OSCManager->StreamingSkeletalMeshTransformMap.Emplace(Port, NewStreamingSkeletalMeshTransform); + + // Bind Port +@@ -149,9 +151,10 @@ UVMC4UEStreamingSkeletalMeshTransform* UVMC4UEBlueprin + + OSCManager->OscReceivers.Emplace(OscReceiver); + +- return NewStreamingSkeletalMeshTransform; ++ StreamingSkeletalMeshTransform = NewStreamingSkeletalMeshTransform; + } +- return nullptr; ++ ++ return StreamingSkeletalMeshTransform; + } + + void UVMC4UEBlueprintFunctionLibrary::RefreshConnection(float Seconds) +``` + +```cpp:VMC4UEBoneMappingAssetFactory.cpp.patch +--- ./VMC4UE/Source/VMC4UEEd/Source/VMC4UEBoneMappingAssetFactory.cpp ++++ ./VMC4UEBoneMappingAssetFactory.cpp +@@ -5,6 +5,8 @@ + #include "../../VMC4UE/Include/VMC4UEStreamingData.h" + #include "Dom/JsonObject.h" + #include "JsonObjectConverter.h" ++#include "UObject/ConstructorHelpers.h" ++#include "UObject/UObjectGlobals.h" + + UVMC4UEBoneMappingAssetFactory::UVMC4UEBoneMappingAssetFactory(const FObjectInitializer &ObjectInitializer) + : Super(ObjectInitializer) +@@ -26,11 +28,12 @@ + return UVMC4UEVRMMapping::StaticClass(); + } + ++ + UObject *UVMC4UEBoneMappingAssetFactory::FactoryCreateText(UClass *InClass, UObject *InParent, FName InName, EObjectFlags Flags, UObject *Context, const TCHAR *Type, const TCHAR *&Buffer, const TCHAR *BuferEnd, FFeedbackContext *Warn) + { + FString TextData = FString(Buffer); + +- UVMC4UEVRMMapping *NewAsset = CastChecked(StaticConstructObject_Internal(InClass, InParent, InName, Flags)); ++ UVMC4UEVRMMapping* NewAsset = NewObject(InParent, InClass, InName, Flags); + if (!IsValid(NewAsset)) + { + return nullptr; +``` + +```sh +$ git clone https://github.com/HAL9HARUKU/VMC4UE + +$ patch -u ./VMC4UE/VMC4UE/Source/VMC4UE/Source/VMC4UEBlueprintFunctionLibrary.cpp < VMC4UEBlueprintFunctionLibrary.cpp.patch +$ patch -u ./VMC4UE/VMC4UE/Source/VMC4UEEd/Source/VMC4UEBoneMappingAssetFactory.cpp < VMC4UEBoneMappingAssetFactory.cpp.patch +``` + +## vrm4uを5.5向けにbuildしてみる + +> この手順は興味がある人以外は読み飛ばすことを推奨します。表情を動かしたい人はこの方法で問題を解決することができません。 + +vrm4uは既に5.5のbuildを[releases](https://github.com/ruyo/VRM4U/releases/tag/20241002)しています。 + +ただいくつかの処理が5,4,0向けのようです。それを書き直してbuildしてみます。 + +```sh +$ git clone https://github.com/ruyo/VRM4U +$ cd VRM4U +$ git reset --hard a261860872936c8654e1705a91cff6f8224dbee5 +$ grep -R 5,4,0 ./Source/*|cut -d : -f 1|xargs sed -i '' 's/5,4,0/5,5,0/g' +$ grep -R 5,5,0 . +``` + +これを先程と同じ手順でue5.5で開いてbuildします。 + +## vrm4u(vmc)はbuild後にも表情を動かせるのだろうか + +わかりません。私の環境下では動きませんでした。他の人も動かない可能性がありますが、issueを読む限り動くようにも思えます。 + +> この問題は`vrm4u 20241007`で修正されました + +issue : https://git.syui.ai/ai/ue/issues/9 + +それではどうするのか。livelink(face)を使います。ここからは少しめんどくさいことになりますが、かなり多くのアプリが必要です。 + +- 動き : webcam motion capture(vmc送信) + vseeface(vmc受信/送信) + vrm4u(vmc受信) +- 表情 : iphone + livelink face + +まず、`vrm4u`は`webcam motion capture`のvmcを直接受信できません。なので、一旦、vseefaceなどのclientで受信する必要があります。それをvrm4uで受信するportに送信します。なお、`vmc4ue`では直接受信できて動きます。また、xr-animator, vseeface, vmc(client)も受信できて動いています。不思議な現象です。 + +vrm4u(vmc)はbuild後は表情が動かないので、表情はlivelinkを使用します。これはiphoneに`livelink face`というappがあります。ueでいくつかのpluginを有効にします。 + +- live link +- apple arkit +- apple arkit face support + +`/VRM4U/Util/Actor/latest/BP_LiveLinkFace`をmapにおいて、`live link subject -> iphone`, `target actor sk -> SK_$name`を設定します。 + +![](/img/ue-2024-10-01-7.36.38.png) + +これでbuildすると表情を動かすことができます。 + +## character(player)にlivelinkを当てるには + +character(player)にlivelinkを当てるにはblueprintを編集する必要があります。characterのdirにでも`BP_LiveLinkFace`をcopyして`BP_Player(CBP_Character)`に追加します。 + +![](/img/ue-2024-10-01-7.36.39.png) + +ここで`BP_LiveLinkFace -> livelink subject -> iphone`をセットしておきます。 + +次に`BP_LiveLinkFace`を以下のような形で`sk_$name`に置き換えます。場所はコメントを参考にしてください。私の場合は見た目をカスタマイズしているので少し複雑です。 + + + +https://blueprintue.com/blueprint/pu_xl52s/ + +## vmcで行くべきか + +基本的には依存関係が少なく使うアプリが少ないほうがいいですね。vmcの更新頻度やclient, vrm1のsupport状況を見るとueはlivelink路線のほうがいいかもしれません。 + +仮に`webcam motion capture -> vrm4u`で表情も体も動かせるならvmcで問題ないですが、表情にlivelinkを使うなら全部統一するのがいいですね。 + +[mocopi](https://apps.apple.com/jp/app/mocopi/id6444393701)や[iclone](https://www.unrealengine.com/marketplace/ja/product/iclone-unreal-live-link)はlivelinkなのでそちらが使えると思います。 diff --git a/content/blog/2024-10-12-wasmer.md b/content/blog/2024-10-12-wasmer.md new file mode 100644 index 0000000..ac4b813 --- /dev/null +++ b/content/blog/2024-10-12-wasmer.md @@ -0,0 +1,29 @@ ++++ +date = "2024-10-12" +tags = ["wasm"] +title = "wasmでwasmer-shを動かしてみる" ++++ + +https://docs.wasmer.io/install + +```sh +$ wasmer run wasmer/wasmer-sh -- --port 4480 --host 127.0.0.1 +``` + +```sh +$ wasmer login +$ wasmer deploy +wasmer/wasmer-sh + +# custom domain +https://docs.wasmer.io/edge/configuration/custom-domains +``` + +https://wterm-syui.wasmer.app/ + +```sh +# https://wterm-syui.wasmer.app/ +$ wasmer run clang/clang example.c -o example.wasm +$ ls +$ ./example.wasm +``` diff --git a/content/blog/2024-10-20-stream.md b/content/blog/2024-10-20-stream.md new file mode 100644 index 0000000..76843a4 --- /dev/null +++ b/content/blog/2024-10-20-stream.md @@ -0,0 +1,80 @@ ++++ +date = "2024-10-20" +tags = ["cloudflare"] +title = "restreamerでobsを配信する" ++++ + +live配信するには様々な方法があり、色々と検討していますが、やはりobsを使うのが一番いいという結論になりました。今回は配信環境を構築する方法を紹介します。 + +https://github.com/obsproject/obs-studio + +## ue5を使うのはリスクが大きく拡張性がない + +pixel streamingを使った配信を考えました。操作機能を無効にして配信する方法です。 + +しかし、これには問題が多かった。 + +例えば、すべての機能をueで実装する必要があります。 + +一応実装してみましたが大変な上に不便が多かった。例えば、ゲームがクラッシュすると音声などが途切れますよね。 + +ue5だけで完結することだけが魅力ですが、拡張性がありませんし、リスクが大きいのです。 + +## restreamerを使う + +次に検討したのは`restreamer`を使う方法です。これは配信serverのようなもので、簡易ですがpageもカスタマイズできます。 + +https://github.com/datarhei/restreamer + +```yml:compose.yaml +services: + + restreamer: + image: datarhei/restreamer + #image: datarhei/restreamer:cuda-latest + ports: + - 8080:8080 + - 1935:1935 + - 6000:6000/udp + restart: always + volumes: + - ./data/config:/core/config + - ./data/data:/core/data +``` + +`8080`がweb, `1935`がrtmp, `6000`がsrtです。rtmpとsrtではsrtのほうが高品質で遅延が少なくなると思います。使わないものはportを閉じてもokです。基本的にはバッティングなどもありますから以下のようにlocahostのportを変えて使うのがいいですね。 + +```yml:compose.yaml +services: + restreamer: + ports: + - 8980:8080 + - 1835:1935 + - 6700:6000/udp +``` + +使い方は簡単で最初にwebにアクセスしてadminを作ります。設定を行い、domain(ip)を`127.0.0.1`にします。ここではsrt protocolを使います。obsで配信をカスタムにしてrestreamerで発行されたurlを使用すればokです。 + +なお、同じserverでない場合はobsに設定するurlはipv4に変換します。 + +```sh +- srt://127.0.0.1:6700 ++ srt://192.168.1.99:6700 +``` + +systemから`expert mode`を選択しましょう。 + +現時点で録画機能はありません。つまり、配信終了時にffmpegでconvertしてdocker volumeに保存し、再視聴が可能になる機能があると嬉しいですね。 + +https://github.com/datarhei/restreamer/issues/692 + +## mediacmsに保存する + +https://github.com/mediacms-io/mediacms + +`mediacms`を使用することで録画をuploadすることは可能です。obsで配信、録画を行い、終了時にmediacmsにuploadする方法です。 + +しかし、別のpageに移動しなければなりませんし、管理システムが異なるので良い方法とは言えません。 + +一番いいのは`youtube`を利用することですが、すべて自前で構築する場合は`restreamer` + `mediacms`が良さそう。 + diff --git a/content/blog/2024-10-21-bbs.md b/content/blog/2024-10-21-bbs.md new file mode 100644 index 0000000..70d3abc --- /dev/null +++ b/content/blog/2024-10-21-bbs.md @@ -0,0 +1,279 @@ ++++ +date = "2024-10-21" +tags = ["cloudflare", "bluesky"] +title = "blueskyのoauthとbbsをlivestream serviceに実装する" ++++ + +youtubeのlivestreamはchatのような書き込みができます。それを再現します。 + +まずはblueskyのoauthが動作するかの確認です。これは[bluesky-social/cookbook](https://github.com/bluesky-social/cookbook/tree/main/python-oauth-web-app)を使います。 + +```sh +# https://github.com/bluesky-social/cookbook/tree/main/python-oauth-web-app +$ cd ./repos/cookbook/python-oauth-web-app +$ rye sync +$ rye run python3 -c 'import secrets; print(secrets.token_hex())'|xargs echo FLASK_SECRET_KEY|tr -d ' ' >> .env +$ rye run python3 generate_jwk.py |xargs echo FLASK_CLIENT_SECRET_JWK|tr -d ' ' >> .env +$ cat .env +$ rye run flask run +``` + +oauthはlocalhostでは動作しません。したがって、`ngrok`, `tailscale`, `cloudflare`などを使用します。個人的にはcloudflareがおすすめです。 + +```sh +$ cloudflared tunnel --url http://localhost:5000 +``` + +表示されるurlにアクセスするとoauthでloginすることができました。oauthの情報はserverに保存されており以後は承認なしにlogin可能となります。 + +## bbsと連携する + +今回はloginしている場合にbbsの書き込みシステムを表示します。 + + + +```html:template/home.html +{% block content %} +{% if g.user %} +

@{{ g.user['handle'] }}

+ +{% endif %} +``` + +bbsを作ります。 + +```toml:Cargo.toml +[package] +name = "rust-bbs" +version = "0.1.0" +edition = "2021" + +[dependencies] +actix-web = "4.0" +rusqlite = { version = "0.28", features = ["bundled"] } +serde = { version = "1.0", features = ["derive"] } +askama = "0.11" +``` + +```rust:src/main.rs +use actix_web::{web, App, HttpServer, HttpResponse, Responder}; +use rusqlite::{Connection, Result as SqliteResult}; +use serde::{Deserialize, Serialize}; +use askama::Template; + +#[derive(Serialize, Deserialize)] +struct Post { + id: i32, + content: String, +} + +#[derive(Template)] +#[template(path = "index.html")] +struct IndexTemplate { + posts: Vec, +} + +#[derive(Template)] +#[template(path = "post.html")] +struct PostTemplate {} + +fn init_db() -> SqliteResult<()> { + let conn = Connection::open("sqlite.db")?; + conn.execute( + "CREATE TABLE IF NOT EXISTS posts ( + id INTEGER PRIMARY KEY, + content TEXT NOT NULL + )", + [], + )?; + Ok(()) +} + +async fn index() -> impl Responder { + let conn = Connection::open("sqlite.db").unwrap(); + let mut stmt = conn.prepare("SELECT id, content FROM posts ORDER BY id DESC").unwrap(); + let posts = stmt.query_map([], |row| { + Ok(Post { + id: row.get(0)?, + content: row.get(1)?, + }) + }).unwrap().filter_map(Result::ok).collect::>(); + + let template = IndexTemplate { posts }; + HttpResponse::Ok().body(template.render().unwrap()) +} + +async fn post_form() -> impl Responder { + let template = PostTemplate {}; + HttpResponse::Ok().body(template.render().unwrap()) +} + +#[derive(Deserialize)] +struct FormData { + content: String, +} + +async fn submit_post(form: web::Form) -> impl Responder { + let conn = Connection::open("sqlite.db").unwrap(); + conn.execute( + "INSERT INTO posts (content) VALUES (?1)", + [&form.content], + ).unwrap(); + + web::Redirect::to("/").see_other() +} + +#[actix_web::main] +async fn main() -> std::io::Result<()> { + init_db().unwrap(); + + HttpServer::new(|| { + App::new() + .route("/", web::get().to(index)) + .route("/post", web::get().to(post_form)) + .route("/submit", web::post().to(submit_post)) + }) + .bind("0.0.0.0:8080")? + .run() + .await +} +``` + +```html:template/index.html + + + + Simple BBS + + +

Simple BBS

+ New Post +
    + {% for post in posts %} +
  • {{ post.content }}
  • + {% endfor %} +
+ + +``` + +```html:template/post.html + + + + New Post + + +

New Post

+
+ +
+ +
+ + +``` + +```yml:compose.yml +services: + web: + build: . + ports: + - "8080:8080" + volumes: + - ./sqlite.db:/sqlite.db +``` + +```sh:Dockerfile.txt +FROM syui/aios + +WORKDIR /usr/src/app +COPY . . +RUN cargo build --release +COPY ./templates /templates +CMD ["/usr/src/app/target/release/rust-bbs"] +``` + +```sh +$ cargo build +$ ./target/debug/rust-bbs + +$ docker compose up +$ curl -sL localhost:8080 +``` + +あとは、iframeからparamでhandleを取得するので、それを使用するようにしたり、cssで見栄えを整えたら完成です。 + +要点だけまとめたので適時修正してください。redirectしたときにurlを変更しないとiframeで呼び出したとき2回目からはhandleが使えません。 + +```rust:src/main.rs +async fn submit_post( + req: HttpRequest, + form: web::Form +) -> Result { + let query = web::Query::::from_query(req.query_string()) + .unwrap_or_else(|_| web::Query(QueryParams { handle: None })); + //let handle = query.handle.clone().filter(|h| !h.is_empty()); + //println!("Debug: Extracted handle: {:?}", handle); + let handle = if !form.handle.is_empty() { + form.handle.clone() + } else { + query.handle.clone().unwrap_or_default() + }; + + println!("Debug: Using handle: {:?}", handle); + + let conn = Connection::open("sqlite.db") + .map_err(|_| ErrorInternalServerError("Database connection failed"))?; + let result = conn.execute( + "INSERT INTO posts (handle, content) VALUES (?1, ?2)", + &[&form.handle, &form.content], + ); + match result { + Ok(_) => { + let redirect_url = if !handle.is_empty() { + format!("/?handle={}", handle) + } else { + "/".to_string() + }; + Ok(HttpResponse::SeeOther() + .append_header(("Location", + redirect_url)) + .finish()) + }, + + //Ok(_) => Ok(web::Redirect::to("/").see_other()), + Err(_) => Err(ErrorInternalServerError("Failed to insert post")), + } +} +``` + +```html:templates/index.html +
+ + + +
+ + +``` + +```html:templates/home.htmll +{% if g.user %} + @{{ g.user['handle'] }} + +{% endif %} +``` diff --git a/content/blog/2024-10-26-frontpage.md b/content/blog/2024-10-26-frontpage.md new file mode 100644 index 0000000..969d57c --- /dev/null +++ b/content/blog/2024-10-26-frontpage.md @@ -0,0 +1,261 @@ ++++ +date = "2024-10-26" +tags = ["cloudflare", "bluesky", "atproto"] +title = "atprotoのfrontpageを触ってみる" +[params] + comment = "3l7nuqahc7q27" ++++ + +前回、live配信にatprotoでoauth loginして掲示板(bbs)に書き込めるサイトを作成し、bbsは簡単にrustで自作したものを使っていました。 + +しかし、やはり機能的に不足していたのと、公式のoauth exampleがpythonで書かれていたため、python + rustでやっていました。 + +そこに[likeandscribe/frontpage](https://github.com/likeandscribe/frontpage)というものを見つけて、これはいいものだと思ったので触っていきます。 + + +詳しくはこちらを見てください。 + +- https://frontpage.fyi/post/tom.frontpage.team/3l6nbjyjmcg2v + +これがどういったものかというと、おそらく、bsky.socialとは別サービスですがoauthでlogin(signin)でき、投稿情報は自身のpdsに保存されるのでしょう。また、`drainpipe`はこう書かれています。 + +> Drainpipe is a atproto firehose consumer written in rust. It knows how to reliably* take messages from the firehose, filter them, and forward them over HTTPs to a webhook receiver some place else on the internet. + +```sh +$ git clone https://github.com/likeandscribe/frontpage +$ cd !$:t + +$ nvm use 20 +$ pnpm i +$ cat turbo.json +$ pnpm exec turbo run --affected type-check +``` + +turboを見て分かる通り、dbはtursoを使用するようです。また、`drainpipe`は`fly.io`ですね。 + +```sh +TURSO_CONNECTION_URL +TURSO_AUTH_TOKEN +``` + +```sh +$ cd packages-rs/drainpipe +$ cargo install diesel_cli --no-default-features --features sqlite +$ diesel setup +$ diesel migration run + +$ cp .env .env.local +FRONTPAGE_CONSUMER_SECRET + +$ docker compose up +``` + +なお、ubuntuなどrustcのversionが古い場合は[rustup](https://rustup.rs/)を使ってpathを設定してください。 + +```sh +$ rustup update + +# ~/.zshrc +export PATH="$HOME/.cargo/bin:$PATH" +. $HOME/.cargo/env +``` + +```sh +$ cd packages/frontpage +$ pnpm exec tsx ./scripts/generate-jwk.mts + +# https://docs.turso.tech/quickstart +$ turso db create +TURSO_CONNECTION_URL +TURSO_AUTH_TOKEN +DRAINPIPE_CONSUMER_SECRET + +$ pnpm run db:generate +$ pnpm run db:migrate + +$ cloudflared tunnel --url http://localhost:3000 + +$ pnpm run dev +``` + +![](https://raw.githubusercontent.com/syui/img/master/other/atproto_frontpage_preview_0001.png) + +基本的に`drainpipe`を裏で動かします。これがpostを取得したり投稿したりします。 + +```sh:packages-rs/drainpipe/.env +# .env.local +- FRONTPAGE_CONSUMER_URL="http://localhost:3000/api/receive_hook" ++ FRONTPAGE_CONSUMER_URL="http://example.com/api/receive_hook" +``` + +## rewrite + +```sh +$ cd packages/frontpage +$ PUBLIC_URL=example.com +$ grep -R frontpage.fyi .|cut -d : -f 1|sed -i "s/frontpage.fyi/$PUBLIC_URL/g" +``` + +`pnpm run start`と`pnpm run dev`では`client_id`が異なります。これは`/oauth/client-metadata.json`を見てください。 + +```.env +# .env.local +# packages/frontpage/lib/auth.ts +VERCEL_PROJECT_PRODUCTION_URL=example.com +VERCEL_BRANCH_URL=example.com +``` + +## local-infra + +self-hostするのに必要なserver構成だと思います。 + +https://github.com/likeandscribe/frontpage/tree/main/packages/frontpage/local-infra + +```sh +$ cd local-infra +$ cat README.md +docker-compose up +Create a test account with ./scripts/create-account.sh +DRAINPIPE_CONSUMER_SECRET=secret +TURSO_CONNECTION_URL=libsql://turso.dev.unravel.fyi +PLC_DIRECTORY_URL=https://plc.dev.unravel.fyi +``` + +これらのnameserverはcaddyを見てください。 + +plcはerrorが出るので、以下のようにします。おそらく、postgresのdatabaseが必要なのでしょう。portsは開けなくて大丈夫です。 + +```yml:docker-compose.yml + plc: + image: ghcr.io/bluesky-social/did-method-plc:plc-f2ab7516bac5bc0f3f86842fa94e996bd1b3815b + container_name: plc + restart: unless-stopped + ports: + - '4000:8080' + depends_on: + - plc_db + env_file: + - ./plc.env + + plc_db: + image: postgres:16-alpine + restart: always + env_file: + - ./postgres.env + volumes: + - ./configs/postgres/init/:/docker-entrypoint-initdb.d/ + - ./data/postgres/:/var/lib/postgresql/data/ + healthcheck: + test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB" + interval: 5s + retries: 20 +``` + +```sh:.env +# plc.env +DEBUG_MODE=1 +LOG_ENABLED=true +LOG_LEVEL=debug +LOG_DESTINATION=1 +PORT=8080 +DATABASE_URL=postgres://postgres:postgres@plc_db/plc +DB_CREDS_JSON='{"username":"postgres","password":"postgres","host":"plc_db","port":"5432","database":"plc"}' +ENABLE_MIGRATIONS=true +DB_MIGRATE_CREDS_JSON='{"username":"postgres","password":"postgres","host":"plc_db","port":"5432","database":"plc"}' +``` + +## pds + +大体の原理が理解できてきたので、わかっていることをまとめます。 + +まずoauth(session)でpdsUrlをgetする感じなのかなと思います。sessionがあれば投稿などは操作できます。 + +```sh +$ grep -R pdsUrl . +./lib/data/user.ts: const pdsUrl = await getPdsUrl(session.user.did); +``` + +あるいは`ws://pds:3000`を使用する可能性も考えられますが、基本は`bsky.network`を使うのだと思います。 + +```sh:packages-rs/drainpipe/.env +RELAY_URL=wss://bsky.network +``` + +次に`unravel.frontpage`についてです。これは主に`collection`に書き込まれているようです。この場合、`frontpage.fyi`と投稿は共通します。 + +```sh +$ grep -R unravel.frontpage ./app ./lib +./app/api/receive_hook/route.ts: if (collection === "fyi.unravel.frontpage.vote") { +./lib/data/atproto/comment.ts:export const CommentCollection = "fyi.unravel.frontpage.comment"; +./lib/data/atproto/vote.ts: collection: "fyi.unravel.frontpage.vote", +./lib/data/atproto/vote.ts: collection: "fyi.unravel.frontpage.vote", +./lib/data/atproto/event.ts: z.literal("fyi.unravel.frontpage.vote"), +./lib/data/atproto/post.ts:export const PostCollection = "fyi.unravel.frontpage.post"; + +# HOST_REVERT=com.unravel.example +# grep -R unravel.frontpage ./app ./lib |cut -d : -f 1|xargs sed -i "s/fyi.unravel.frontpage/${HOST_REVERT}/g" +``` + +```js +// https://atproto.com/ja/guides/applications +// レコードの時間ベースのキーを生成します +const rkey = TID.nextStr() + +// 書き込み +await agent.com.atproto.repo.putRecord({ + repo: agent.assertDid, // ユーザー + collection: 'xyz.statusphere.status', // コレクション + rkey, // レコード キー + record: { // レコード値 + status: "👍", + createdAt: new Date().toISOString() + } +}) +``` + +`drainpipe`はpdsの`fyi.unravel.frontpage(collection)`を検索してfirehoseの`subscribeRepos`にcommitするようです。この2つの部分を変更すると`frontpage.fyi`と連動しません。 + +```rust:packages-rs/drainpipe/src/main.rs +let mut ws_request = format!( + "{}/xrpc/com.atproto.sync.subscribeRepos{}", + relay_url, query_string +) + +// https://github.com/likeandscribe/frontpage/blob/e7444ec6c19f0ccef3776f04702c3bb033ed3bfc/packages-rs/drainpipe/src/main.rs#L66-L97 +/// Process a message from the firehose. Returns the sequence number of the message or an error. +async fn process(message: Vec, ctx: &mut Context) -> Result { + let (_header, data) = firehose::read(&message).map_err(|e| ProcessError { + inner: e.into(), + seq: -1, + source: message.clone().into(), + kind: ProcessErrorKind::DecodeError, + })?; + let sequence = match data { + firehose::SubscribeRepos::Commit(commit) => { + let frontpage_ops = commit + .operations + .iter() + .filter(|op| op.path.starts_with("com.unravel.example.")) + //.filter(|op| op.path.starts_with("fyi.unravel.frontpage.")) + .collect::>(); + if !frontpage_ops.is_empty() { + process_frontpage_ops(&frontpage_ops, &commit, &ctx) + .map_err(|e| ProcessError { + seq: commit.sequence, + inner: e, + source: message.clone().into(), + kind: ProcessErrorKind::ProcessError, + }) + .await?; + } + commit.sequence + } + msg => msg.sequence(), + }; + + Ok(sequence) +} +``` + +ただ、infraのpdsは`pds.dev.unravel.fyi`となっていて、中の人の話を聞くと`frontpage.fyi`のpdsにpostされるように感じました。 + diff --git a/content/m/genshin/index.md b/content/m/genshin/index.md index bcd1424..6fefe2e 100644 --- a/content/m/genshin/index.md +++ b/content/m/genshin/index.md @@ -57,6 +57,7 @@ header_image = "/games/genshin.jpg" |2023|04|`ナヒーダ`を完凸|初めての完凸| |2023|11|`フリーナ`を2凸|スカークが実装されたら完凸したい| |2024|04|`ヌヴィレット`を1凸|螺旋単騎やってみた| +|2024|10|`シロネン`を確保|炎神と氷神を完凸予定なので1人につき原石が90,000必要| [![](https://raw.githubusercontent.com/syui/img/master/other/genshin_20220701_0001.png)](https://raw.githubusercontent.com/syui/img/master/other/genshin_20220701_0001.png) @@ -73,19 +74,17 @@ header_image = "/games/genshin.jpg" |3| ヌヴィレット| |4| 雷電 / 鍾離| -|元素|キャラ|特徴| -|---|---|---| -|雷|忍|スキルでの回復及び継続的な元素反応| -|炎|ベネット|爆発で回復とバフ、短時間スキル| -|炎|香菱|強力な爆発| -|水|行秋|強力な爆発、スキルの攻撃力とエネルギー回復力| +まずは各元素の強キャラを1人確保して、余裕が出てくれば2人確保しましょう。 -補足として以下のキャラは育成しておいて損はないと思います。 - -|元素|キャラ|特徴| -|---|---|---| -|草|蛍|元素別では最強の主人公| -|氷|レイラ|氷シールド| +|元素|キャラ1|キャラ2|凸| +|---|---|---|---| +|風|ウェンティ|万葉|無凸/無凸| +|岩|鍾離|シロネン|無凸/無凸| +|雷|雷電|忍|無凸/完凸| +|草|ナヒーダ|蛍|完凸/5凸| +|水|フリーナ(ヌヴィレット)|行秋|2凸/完凸| +|炎|---|香菱/ベネット|完凸/完凸| +|氷|---|レイラ|---/完凸| #### 元素 @@ -128,6 +127,7 @@ header_image = "/games/genshin.jpg" |2023|04|40,000|-40,000|0|ナヒーダ(完凸)| |2023|11|44,000|-22,000|22,000|フリーナ(2凸)| |2024|04|55,000|-30,000|25,000|ヌヴィレット(1凸)| +|2024|10|75,000|-8,000|65,000|シロネン| - スターダスト変換した運命も合算しています diff --git a/content/m/ue.md b/content/m/ue.md index 328aee2..0c1408f 100644 --- a/content/m/ue.md +++ b/content/m/ue.md @@ -8,7 +8,7 @@ slug = "ue" ここでは[epic games](https://www.epicgames.com/)の[unreal engine 5](https://www.unrealengine.com/ja/unreal-engine-5)の使い方をまとめます。現在はversionの`5.4.2`に追従しています。 -- [ue 5.4.2](https://dev.epicgames.com/documentation/ja-jp/unreal-engine/unreal-engine-5.4-release-notes) +- [ue 5.4.4](https://dev.epicgames.com/documentation/ja-jp/unreal-engine/unreal-engine-5.4-release-notes) - [ue 5.3.2](https://dev.epicgames.com/documentation/ja-jp/unreal-engine/unreal-engine-5.3-release-notes) ブログで説明しづらい部分が多いので[blueprintue](https://blueprintue.com/profile/ai/)を参考にしてください。 @@ -730,6 +730,53 @@ https://logicalbeat.jp/blog/11044/ 5.3から5.4にシーケンサを持ってきて使用していましたが、一度でも編集するとおかしくなります。例えば、BP_Playerを置いたとして、mesh(skeltal)も追加しなければならなくなりました。なぜならanimを追加できないからです。meshを追加したあとanimを追加できます。しかし、これでもまだ正常ではありません。buildが進まなくなり、編集するとanimが機能しなくなります。つまり、meshを追加、animを追加、meshを削除という手順を踏まなければいけません。BP_Playerの直下にanimを置くことでようやく正常になります。 これは5.4.3にしたら治りました。基本的にはskeltal meshがSKM_UEFN_Mannequinのもの`CharacterMesh0`を置いて、その下にanimを置きます。この際、Mannequinのanimが必要です。リターゲットで作成します。そして、transformを0にしておいてください。animは右クリックで`ルートコンポーネントを交換`にしておくといいかもしれません。 +今もbuild後の画質問題に悩まされています。私はcity sampleをベースにprojectを作成し、package buildしていますが、build後は画質が悪くなります。editor上では問題ありません。`高DPIを許可`なども試してみましたが効果がありませんでした。 + +以下のようなscalability(エンジン拡張機能設定)をしています。DeviceProfilesでも設定できます。ツール -> プラットフォーム -> デバイスプロファイル -> Windows, rはレンダリングで、sgはscalability group + +``` +#DefaultEngine.ini +[ConsoleVariables] +sg.AntiAliasingQuality=4 +sg.EffectsQuality=4 +sg.FoliageQuality=4 +sg.GlobalIlluminationQuality=4 +sg.LandscapeQuality=4 +sg.ReflectionQuality=4 +sg.ResolutionQuality=100 +sg.ShadingQuality=4 +sg.ShadowQuality=4 +sg.PostProcessQuality=4 +sg.TextureQuality=4 +sg.ViewDistanceQuality=4 +r.MaterialQualityLevel=3 + +#DefaultScalability.ini +[ScalabilitySettings] +sg.AntiAliasingQuality=4 +sg.EffectsQuality=4 +sg.FoliageQuality=4 +sg.GlobalIlluminationQuality=4 +sg.LandscapeQuality=4 +sg.ReflectionQuality=4 +sg.ResolutionQuality=100 +sg.ShadingQuality=4 +sg.ShadowQuality=4 +sg.PostProcessQuality=4 +sg.TextureQuality=4 +sg.ViewDistanceQuality=4 +``` + +また、blueprintで`r.SetRes 1920x1080f`や`Set Screen Resolution`+`Apply Settings`を実行し、build後のwidgetから確認済みです。`Get Game User Settings`から`Get Screen Resolution`して`1920x1080`が表示されています。ウィンドウ形式なども`Set Fullscreen Mode`で変更できているようです。念の為`.ini`に以下の項目なども追加しています。 + +``` +[ConsoleVariables] +r.SetRes=1920x1080f +``` + +他にはゲーム中にscalabilityやscreen size(Screen Resolution)を変更できるようにしていて、これを変更すると画質や表示が切り替わっているように感じます。ウィンドウ形式は確実に切り替えられます。 + +ただ、肝心のタイトル文字はぼやけていて、ゲーム中の雲の画質が解像度でいうと`1280x720`相当になってしまいます。雲はdynamic volumetric skyを使用しており、editor上の画質に問題はありません。 ## [tips] vrm4uの見た目の調整 @@ -1035,3 +1082,199 @@ modelにつけるアクセサリをblenderで統合させ、three-vrmで表示 `unity + vrm 1.0`でアクセサリを付けて、exportしましょう。 +## [issue] build後の画質問題 + +今もbuild後の画質問題に悩まされています。私はcity sampleをベースにprojectを作成し、package buildしていますが、build後は画質が悪くなります。editor上では問題ありません。`高DPIを許可`なども試してみましたが効果がありませんでした。 + +![](/m/post/ue/ue5_2024-08-12_01.png) + +左:build / 右:editor + +以下のようなscalability(エンジン拡張機能設定)をしています。DeviceProfilesでも設定できます。ツール -> プラットフォーム -> デバイスプロファイル -> Windows, rはレンダリングで、sgはscalability group + +``` +#DefaultEngine.ini +[ConsoleVariables] +sg.AntiAliasingQuality=4 +sg.EffectsQuality=4 +sg.FoliageQuality=4 +sg.GlobalIlluminationQuality=4 +sg.LandscapeQuality=4 +sg.ReflectionQuality=4 +sg.ResolutionQuality=100 +sg.ShadingQuality=4 +sg.ShadowQuality=4 +sg.PostProcessQuality=4 +sg.TextureQuality=4 +sg.ViewDistanceQuality=4 +r.MaterialQualityLevel=3 + +#DefaultScalability.ini +[ScalabilitySettings] +sg.AntiAliasingQuality=4 +sg.EffectsQuality=4 +sg.FoliageQuality=4 +sg.GlobalIlluminationQuality=4 +sg.LandscapeQuality=4 +sg.ReflectionQuality=4 +sg.ResolutionQuality=100 +sg.ShadingQuality=4 +sg.ShadowQuality=4 +sg.PostProcessQuality=4 +sg.TextureQuality=4 +sg.ViewDistanceQuality=4 +``` + +また、blueprintで`r.SetRes 1920x1080f`や`Set Screen Resolution`+`Apply Settings`を実行し、build後のwidgetから確認済みです。`Get Game User Settings`から`Get Screen Resolution`して`1920x1080`が表示されています。ウィンドウ形式なども`Set Fullscreen Mode`で変更できているようです。念の為`.ini`に以下の項目なども追加しています。fはfull, wはwindowed + +``` +[ConsoleVariables] +r.SetRes=1920x1080f +``` + +> Unreal Engineのr.SetResコマンドは、画面やウィンドウの解像度を変更するために使用されます。このコマンドは、解像度を指定した後にオプションでウィンドウモードを示すことで構成されます。例えば、r.SetRes 1920x1080wは1920x1080のウィンドウモードに設定し、r.SetRes 1920x1080fはフルスクリーンモードに設定します。ただし、特定のバージョンのUnreal Engine(例えば4.5.1)では、r.SetResコマンドが信頼性を持って動作しないという報告があります。特にウィンドウモードからフルスクリーンモードに切り替える際に、解像度が正しく更新されないという問題が発生しています。この不具合はハードウェアやドライバの特性に関連している可能性があり、ウィンドウモードの方がフルスクリーンよりも信頼性が高いと指摘されています。Unreal Engine 5.1では、解像度やその他の画面設定は一般的にUGameUserSettingsクラスを通じて管理され、特定のプロジェクトニーズに合わせてカスタマイズすることができます。 + +他にはゲーム中にscalabilityやscreen size(Screen Resolution)を変更できるようにしていて、これを変更すると画質や表示が切り替わっているように感じます。ウィンドウ形式は確実に切り替えられます。 + +ただ、肝心のタイトル文字はぼやけていて、ゲーム中の雲の画質が解像度でいうと`1280x720`相当になってしまいます。雲はdynamic volumetric skyを使用しており、editor上の画質に問題はありません。 + +その後、dynamic volumetric skyの雲や時間が動いていない事に気づきました。editorでは動いていますが、buildは動いていません。他のassetやmap(level)は動いています。これが雲の画質に関係しているのかもしれません。ただ、そう考えるとタイトル文字のぼやけが奇妙です。 + +## [close] build後の画質問題 + +特にdynamic volumetric skyの画質問題は`BP_DynamicVolumetricSky`のSingle Player Fps Lockを`Free`にしていると発生するようです。これを`60 FPS`に変更すると雲が動くようになり、画質も改善されました。 + +ただ、タイトル文字の画質は改善されていません。 + +> nvidiaの`グラフィック -> グローバル設定`が原因で、アプリが新しくなったからとインストール通知が来てて、そこから低画質が始まってたっぽい。イメージスケーリング(maxが解像度85%)をオフにすると治った。この設定は一体何なのだろう。windowsとゲームで設定できるから解像度はそれでいいと思ってた。でも違った。windows + ue + nvidiaの全部で解像度をうまく設定しないとおかしくなる。 + +## [issue] loading widget + +ue5はloading画面を作るのにも苦労します。個人的にはwidgetがそもそも使いづらいのと、open levelの扱いがおかしいのです。例えば、widgetは`all remove`しか用意されていません。 + +私はprojectのconfigを用意して、変数にwidget blueprint(loading)のobjectを作成し、BP_Playerのevent beginでcreate widgetしてから、cast configからset loadingしています。 + +ocean waveは少し特殊で読み込みが遅いので、ここで待たなければなりません。ocean waveの読み込みが終わったときconfigから取ってきたloading(object)を`remove parent`します。 + +```sh +title -> create loading -> open level -> bp_palyer -> create loading, set config -> ocean wave(loadend) -> cast config -> remove parent +``` + +### [issue] 家を置くとexeが落ちる + +> 建物の上に浮かんでいる輪っかみたいなactorを消したら正常に動くようになった。なんか変なのが浮かんでいると思っていた。`WeatherOccluder` + +ビデオメモリが足りないと言われ落ちます。editorでは落ちません。 + +円形の家でライトは周りを取り囲むように設置されてて、それが重くなる一つの要因だとは思ってた。ちょっとおかしいけど、でもライトを少なくすると落ちなくなったのでそれが原因だったぽい。 + +ちなみに、ビデオメモリは足りてる。全然使っていない。最初の読み込みのところでmapが起動しない。小さな家の中にあるライトが原因でゲームが起動しないなんてこと普通ないと思うけど。 + +その後、また落ちるようになり、今度はライトを消しても落ちるようになったみたいだ。試しにコードをうまく行ったときの状態に戻してbuildしてみると落ちる。 + +### [issue] city sampleで少しでも遠ざかると追加したactorが消える + +これはcity sampleに持ってくるといつの間にかインスタンスの親子関係がバラバラに解除されるからです。 + +最初はうまく構成されていますが、いつの間にかおかしいフォルダ構成になっていたり、親子付が解除されていたりします。 + +一度アプリを落とすと次に起動したときにはおかしくなっているのでしょう。 + +つまり、保存したものがいつの間にか勝手に変更されているのです。ですから場合によっては気づかないことがあります。 + +actorをまたもとのインスタンス下に置くと遠ざかっても建物が消えないようになります。 + +これはあらゆるものをcity sampleに追加するときに見られる挙動でもあります。 + +追加するとそのときは問題ないのですが、アプリを落とした以降におかしな挙動や構成になり再設定しないと適切に描写されず、距離に応じて消えてしまうactorになります。 + +また、再度設定して親子付けしたはずのものがいつの間にか解除されてたりもします。描写されないのでおかしいなと見てみると勝手に変更されています。定期的にあるので、毎回チェックするのが大変です。 + +色々な距離設定やプロジェクト設定、ワールド設定を見てみましたが、どれも効果を発揮しませんでした。 + +> 目の前のactorしか表示しないのは負荷軽減になります。正常な描写に戻すよう努力することでビデオメモリが足りないと落ちる可能性が高まります。ただ、ビデオメモリが足りなくなるようなものは追加していないし、負荷を監視していますがメモリは足りているので、ue(もしくはcity sample)が壊れているのかもしれません。その証拠にeditorからの起動では落ちません。あるいはdynamic volumetric skyとocean wavesを追加したことで相当な負荷がかかっており、少しactorを追加するだけでも落ちるようになっている可能性もあります。 + +### [tips] twinmotionがすり抜け + +twinmotionで実装するものはcollisionが設定されていないのですり抜けます。 + +これを解消するにはmeshを全選択して、右クリックで`アセットアクション -> プロパティマトリクスで選択内容を... -> collision complexity(use complex collision as simple...)`を選択します。 + +これはtwinmotionに限らず`AutomotiveBridgeScene`にも見られる挙動でした。とはいえ設置したい場所にもよります。 + +### [issue] nvidiaの画面がちらつく + +特にue5でひどかった画面のチラ付きに対処するには、nvidiaコントロールパネルを開いて解像度の変更からリフレッシュレートをディスプレイに合わせたあと`nvidiaのカラー設定を使用`を選択して再起動します。 + +### [tips] 音声を読み取り、chatgptで変換する + +https://github.com/gtreshchev/RuntimeSpeechRecognizer/wiki/1.-How-to-use-the-plugin + +https://www.youtube.com/watch?v=xBs-nXzXwoM&list=LL&index=1 + +- https://github.com/gtreshchev/RuntimeSpeechRecognizer +- https://github.com/gtreshchev/RuntimeAudioImporter +- https://blueprintue.com/blueprint/et6u52bm/ + +最後の`Get Sample Rate -> Process Audio Data(Sample Rate)`のところだけコピーでは対応できないので手動でつなげること。 + +### [tips] city sampleのbgmをcustomする + +[suno](https://suno.com/@syui)を使用して作ると良いでしょう。 + +https://www.youtube.com/watch?v=99uP2WuU2Jo + +`Audio/MetaSounds/Music/music_leavebehind_New_mix_Meta`を編集して、引用されているbaseの音楽を変更します。ただし、補助楽器を鳴らしているものは変更しません。 + +基本的にはそれぞれのパターンに合わせて、baseとなるbgmを改変して複数用意して入れていきます。そこまで面倒な手間をかけていられない場合は全部同じものを入れます。 + +### [issue] build後にcity sampleの風の音が消える + +```sh +# [close] +この問題は最初にPlayStartする場所が鍵でした。私は上空の家でスタートさせているのですが、これを地上でスタートさせるようにしなければなりません。 +あるいは、再度スタートさせる場所を変更、移動して読み込みましょう。 +``` + +build後にcity sampleの風の音が消えていることに気づいた。 + +いつ頃から消えていたかはよくわからないけど、多分、音声認識のpluginを入れてからだと思う。 + +しかし、おかしなところはopen levelでまずはtitle画面を読み込んでそこからmapに移行するんだけど、title画面では風の音が聞こえている。mapに移行してから消える。 + +それもただ消えるだけじゃなく、他の音は聞こえる。他の音もcity sampleの同じシステムで作成、管理されている。 + +でも風の音だけ消えているように思う。なお、これらの問題はeditorやpreviewでは確認できず、あくまでbuild後のpackage(exe)で発生している。 + +参照ビューアで辿っていると、`Script/CitySampleWorldAudioDataScript`に行き当たり、そこで`MetaSounds/Ambint/sfx_amb_Pawn_Wind_lp_meta`を追加したがbuild後に再生されていない。 + +### [tips] ultra dynamic skyの雲がきれいになった + +updateが来てから雲の質が上がったので、`dynamic volumetric sky`と比べてもそこまで差がないです。したがって、天候もあるultra skyを使用することにしました。ちなみに、未だ雲の質はdynamic skyのほうが少し上です。 + +oceanと同時に使うには`BP_EarthSizedSphericalMesh`のtransform-location-zを`-636000100`にすると波紋が軽減される。ただし、この問題を完全に解決するには、sky-atmosphereを惑星の中心にするしかなく、ultra skyはそれだと問題が発生します。 + +### [issue] 画面がチカチカする2 + +nvidiaのスケーリングをONにしたら治った。でもこれをONにするとbuildしたpackageで雲の画質が悪くなったのを思い出した。 + +### [tips] 音声で操作する + +これは前からやろうか迷ってたけど、簡単に実装できる。 + +configで音声を保存してstatus画面でも表示する。 + +### [tips] 音声でNPCを喋らせる + +まず音声認識からchatgpt,elevenlabsを使うのは前回まででやっているけど、これを利用するとNPCを喋らせることができる。 + +この場合、会話のバリエーションは無限大だが制御はできない。 + +NPC(collision)にあたったとき、configにNPCのnumを入れてボタンが表示されるようにする。キーを押すとchatgptにNPCの設定をいれる。 + +### [issue] ビデオメモリ不足で落ちる2 + +これはまず重くないmapを開くことで次に開くmapをクラッシュを防ぐことができます。起動後にすぐ重いmapを開くと大体はクラッシュします。 + +ちなみに、原因はわかりませんし、メモリは不足していません。おそらく、GPUの性能にかかわらずクラッシュすると思われます。 + diff --git a/content/m/ue/ue5_2024-08-12_01.png b/content/m/ue/ue5_2024-08-12_01.png new file mode 100644 index 0000000..8e8b8ff Binary files /dev/null and b/content/m/ue/ue5_2024-08-12_01.png differ diff --git a/content/m/ue/ue5_2024-08-15_01.mp4 b/content/m/ue/ue5_2024-08-15_01.mp4 new file mode 100644 index 0000000..5df9688 Binary files /dev/null and b/content/m/ue/ue5_2024-08-15_01.mp4 differ diff --git a/layouts/_default/single.html b/layouts/_default/single.html index 7a0d3af..28db61e 100644 --- a/layouts/_default/single.html +++ b/layouts/_default/single.html @@ -4,7 +4,7 @@
{{ if ne .Lastmod .Date }}
update : {{ .Lastmod.Format "2006-01-02" }}
{{ end }} -
{{ .Date.Local.Format "2006-01-02" }} / @{{ .Site.Author.name }} +
{{ .Date.Local.Format "2006-01-02" }} / @{{ .Site.Params.Author.name }} {{ $taxo := "tags" }} {{ with .Param $taxo }} @@ -50,9 +50,16 @@ -->
+
-{{ partial "comment.html" . }} +{{ if .Param "comment" }} + +{{ end }} + {{ partial "footer.html" . }} diff --git a/layouts/partials/comment.html b/layouts/partials/comment.html index 7e8eace..f661cf5 100644 --- a/layouts/partials/comment.html +++ b/layouts/partials/comment.html @@ -1,6 +1,9 @@ + + diff --git a/layouts/partials/head-blog.html b/layouts/partials/head-blog.html index 1a0b115..59d3837 100644 --- a/layouts/partials/head-blog.html +++ b/layouts/partials/head-blog.html @@ -3,8 +3,8 @@ {{ .Title }} | {{ .Site.Title }} - - + + diff --git a/layouts/partials/head-nyan.html b/layouts/partials/head-nyan.html index ce625c9..7051c7b 100644 --- a/layouts/partials/head-nyan.html +++ b/layouts/partials/head-nyan.html @@ -2,8 +2,8 @@ {{ .Title }} - - + + diff --git a/layouts/partials/head-pico.html b/layouts/partials/head-pico.html index 39bfb5e..e47204a 100644 --- a/layouts/partials/head-pico.html +++ b/layouts/partials/head-pico.html @@ -2,8 +2,8 @@ {{ .Title }} - - + + diff --git a/layouts/partials/head.html b/layouts/partials/head.html index 1fcdc39..5ec761d 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -3,8 +3,8 @@ {{ .Title }} - - + + diff --git a/static/css/blog.css b/static/css/blog.css index ee4a3fa..71242df 100644 --- a/static/css/blog.css +++ b/static/css/blog.css @@ -126,10 +126,6 @@ button.comment_open:hover { margin: 0px auto; } -.comment { - background-color: #fff; -} - article p img { width: 100%; padding:0; diff --git a/static/css/style.css b/static/css/style.css index aa677de..eff2220 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3,6 +3,7 @@ body { background-color: #f1f1f1; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; width:100%; + margin:0; padding: 0; -webkit-text-size-adjust: 100%; @@ -354,9 +355,7 @@ button.comment_open:hover { margin: 0px auto; } -.comment { - background-color: #fff; -} + .loading { background:#f1f1f1; @@ -398,3 +397,31 @@ span.icon-syui { } } +iframe.frontpage { + width:100%; + height: 1000px; + pointer-events:none; + border: 2px solid #fff; +} + +a.frontpage-button { + width:100%; + font-size: 15px; + background-color: #e80063; + /* background-color: #007fff; */ + color: #fff; + border: 2px solid #fff; + padding: 10px 30px; + border-radius: 5px; + text-decoration: none; +} + +a.frontpage-button:hover { + /* background-color: #0077ff; */ + background-color: #e80073; +} + +.comment { + background-color: #f1f1f1; +} + diff --git a/static/img/holo.mov b/static/img/holo.mov new file mode 100644 index 0000000..009b9ab Binary files /dev/null and b/static/img/holo.mov differ diff --git a/static/img/ue-2024-10-01-7.36.38.png b/static/img/ue-2024-10-01-7.36.38.png new file mode 100644 index 0000000..7ffba29 Binary files /dev/null and b/static/img/ue-2024-10-01-7.36.38.png differ diff --git a/static/img/ue-2024-10-01-7.36.39.png b/static/img/ue-2024-10-01-7.36.39.png new file mode 100755 index 0000000..b491351 Binary files /dev/null and b/static/img/ue-2024-10-01-7.36.39.png differ diff --git a/static/img/windows_terminal_sixel.png b/static/img/windows_terminal_sixel.png new file mode 100644 index 0000000..b2dce55 Binary files /dev/null and b/static/img/windows_terminal_sixel.png differ