mulmocast 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +74 -0
  2. package/assets/audio/silent300.mp3 +0 -0
  3. package/assets/audio/silent800.mp3 +0 -0
  4. package/assets/music/StarsBeyondEx.mp3 +0 -0
  5. package/assets/templates/business.json +89 -0
  6. package/assets/templates/children_book.json +135 -0
  7. package/assets/templates/podcast_standard.json +5 -0
  8. package/assets/templates/sensei_and_taro.json +123 -0
  9. package/lib/actions/audio.d.ts +3 -0
  10. package/lib/actions/audio.js +186 -0
  11. package/lib/actions/images.d.ts +2 -0
  12. package/lib/actions/images.js +211 -0
  13. package/lib/actions/movie.d.ts +2 -0
  14. package/lib/actions/movie.js +81 -0
  15. package/lib/actions/translate.d.ts +3 -0
  16. package/lib/actions/translate.js +236 -0
  17. package/lib/agents/add_bgm_agent.d.ts +3 -0
  18. package/lib/agents/add_bgm_agent.js +61 -0
  19. package/lib/agents/combine_audio_files_agent.d.ts +3 -0
  20. package/lib/agents/combine_audio_files_agent.js +57 -0
  21. package/lib/agents/image_google_agent.d.ts +15 -0
  22. package/lib/agents/image_google_agent.js +88 -0
  23. package/lib/agents/image_openai_agent.d.ts +15 -0
  24. package/lib/agents/image_openai_agent.js +59 -0
  25. package/lib/agents/index.d.ts +13 -0
  26. package/lib/agents/index.js +31 -0
  27. package/lib/agents/mulmo_prompts_agent.d.ts +7 -0
  28. package/lib/agents/mulmo_prompts_agent.js +41 -0
  29. package/lib/agents/prompts_data.d.ts +15 -0
  30. package/lib/agents/prompts_data.js +19 -0
  31. package/lib/agents/tts_nijivoice_agent.d.ts +4 -0
  32. package/lib/agents/tts_nijivoice_agent.js +68 -0
  33. package/lib/agents/tts_openai_agent.d.ts +4 -0
  34. package/lib/agents/tts_openai_agent.js +50 -0
  35. package/lib/agents/validate_mulmo_script_agent.d.ts +17 -0
  36. package/lib/agents/validate_mulmo_script_agent.js +38 -0
  37. package/lib/cli/args.d.ts +10 -0
  38. package/lib/cli/args.js +38 -0
  39. package/lib/cli/cli.d.ts +2 -0
  40. package/lib/cli/cli.js +78 -0
  41. package/lib/cli/common.d.ts +8 -0
  42. package/lib/cli/common.js +26 -0
  43. package/lib/cli/tool-args.d.ts +12 -0
  44. package/lib/cli/tool-args.js +53 -0
  45. package/lib/cli/tool-cli.d.ts +2 -0
  46. package/lib/cli/tool-cli.js +78 -0
  47. package/lib/methods/index.d.ts +3 -0
  48. package/lib/methods/index.js +19 -0
  49. package/lib/methods/mulmo_script.d.ts +11 -0
  50. package/lib/methods/mulmo_script.js +45 -0
  51. package/lib/methods/mulmo_script_template.d.ts +4 -0
  52. package/lib/methods/mulmo_script_template.js +22 -0
  53. package/lib/methods/mulmo_studio_context.d.ts +4 -0
  54. package/lib/methods/mulmo_studio_context.js +12 -0
  55. package/lib/tools/dump_prompt.d.ts +3 -0
  56. package/lib/tools/dump_prompt.js +9 -0
  57. package/lib/tools/prompt.d.ts +1 -0
  58. package/lib/tools/prompt.js +20 -0
  59. package/lib/tools/seed.d.ts +3 -0
  60. package/lib/tools/seed.js +201 -0
  61. package/lib/tools/seed_from_url.d.ts +3 -0
  62. package/lib/tools/seed_from_url.js +178 -0
  63. package/lib/types/index.d.ts +1 -0
  64. package/lib/types/index.js +17 -0
  65. package/lib/types/schema.d.ts +5817 -0
  66. package/lib/types/schema.js +207 -0
  67. package/lib/types/type.d.ts +33 -0
  68. package/lib/types/type.js +2 -0
  69. package/lib/utils/const.d.ts +3 -0
  70. package/lib/utils/const.js +6 -0
  71. package/lib/utils/file.d.ts +28 -0
  72. package/lib/utils/file.js +112 -0
  73. package/lib/utils/filters.d.ts +3 -0
  74. package/lib/utils/filters.js +32 -0
  75. package/lib/utils/markdown.d.ts +1 -0
  76. package/lib/utils/markdown.js +27 -0
  77. package/lib/utils/preprocess.d.ts +247 -0
  78. package/lib/utils/preprocess.js +53 -0
  79. package/lib/utils/string.d.ts +9 -0
  80. package/lib/utils/string.js +60 -0
  81. package/lib/utils/text_hash.d.ts +1 -0
  82. package/lib/utils/text_hash.js +41 -0
  83. package/package.json +77 -0
package/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # mulmo
2
+
3
+ A CLI tool for generating podcast and video content from script files. Automates the process of creating audio, images, and video from structured script files.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g mulmo
9
+ ```
10
+
11
+ You'll also need to install ffmpeg:
12
+ ```bash
13
+ # For macOS with Homebrew
14
+ brew install ffmpeg
15
+
16
+ # For other platforms
17
+ # Visit https://ffmpeg.org/download.html
18
+ ```
19
+
20
+ ## Configuration
21
+
22
+ Create a `.env` file in your project directory with the following API keys:
23
+
24
+ ```
25
+ OPENAI_API_KEY=your_openai_api_key
26
+ GOOGLE_PROJECT_ID=your_google_project_id # optional for movie, image generation
27
+ NIJIVOICE_API_KEY=your_nijivoice_api_key # optional for movie, audio generation
28
+ BROWSERLESS_API_TOKEN=your_browserless_api_token # optional for scripting from web content
29
+ ```
30
+
31
+ ## Workflow
32
+
33
+ 1. Create a MulmoScript JSON file with `mulmo-tool scripting`
34
+ 2. Generate audio with `mulmo audio`
35
+ 3. Generate images with `mulmo images`
36
+ 4. Create final video with `mulmo movie`
37
+
38
+ ## Generate MulmoScript
39
+
40
+ ```bash
41
+ # Generate script from web content
42
+ mulmo-tool scripting -u https://example.com -t seed_materials
43
+
44
+ # Generate script with interactive mode
45
+ mulmo-tool scripting -i -t seed_interactive
46
+ ```
47
+
48
+ ## Generate content from MulmoScript
49
+
50
+ Mulmo provides several commands to handle different aspects of content creation:
51
+
52
+ ```bash
53
+ # Generate audio from script
54
+ mulmo audio -f script.json
55
+
56
+ # Generate images for script
57
+ mulmo images -f script.json
58
+
59
+ # Generate both audio and images, then combine into video
60
+ mulmo movie -f script.json
61
+
62
+ # Translate script to Japanese
63
+ mulmo translate -f script.json
64
+ ```
65
+
66
+ ## MulmoScript Format
67
+
68
+ MulmoScript is a JSON format to define podcast or video scripts:
69
+ schema: [./src/types/schema.ts](./src/types/schema.ts)
70
+
71
+
72
+ ## Contributing
73
+
74
+ For developers interested in contributing to this project, please see [CONTRIBUTING.md](./CONTRIBUTING.md).
Binary file
Binary file
Binary file
@@ -0,0 +1,89 @@
1
+ {
2
+ "title": "Business presentation",
3
+ "description": "Template for children book.",
4
+ "systemPrompt": "Generate a script for a business presentation of the given topic. Use textSlides or markdown to show slides or use imagePrompt to generate an appropriate image for that page. Use the JSON below as a template",
5
+ "script": {
6
+ "$mulmocast": {
7
+ "version": "1.0",
8
+ "credit": "closing"
9
+ },
10
+ "title": "Sample Title",
11
+ "canvasSize": {
12
+ "width": 1536,
13
+ "height": 1024
14
+ },
15
+ "imageParams": {
16
+ "style": "Style appropriate for business environment.",
17
+ "model": "gpt-image-1",
18
+ "size": "1536x1024"
19
+ },
20
+ "speechParams": {
21
+ "speakers": {
22
+ "Presenter": {
23
+ "voiceId": "shimmer",
24
+ "displayName": {
25
+ "en": "Presenter",
26
+ "ja": "語り手"
27
+ }
28
+ }
29
+ }
30
+ },
31
+ "lang": "en",
32
+ "beats": [
33
+ {
34
+ "speaker": "Presenter",
35
+ "text": "Today we're exploring a fascinating concept that has shaped some of the most innovative companies and leaders of our time: the Reality Distortion Field. This term has become synonymous with visionary leadership and the ability to accomplish seemingly impossible goals.",
36
+ "image": {
37
+ "type": "textSlide",
38
+ "slide": {
39
+ "title": "This is the title of this slide",
40
+ "bullets": []
41
+ }
42
+ },
43
+ "textSlideParams": {
44
+ "cssStyles": ["h1 { margin-top: 400px }"]
45
+ }
46
+ },
47
+ {
48
+ "speaker": "Presenter",
49
+ "text": "The evolution of humans is a complex journey that spans millions of years, shaped by biology, environment, and culture. Here's a high-level summary of the key stages in human evolution",
50
+ "image": {
51
+ "type": "textSlide",
52
+ "slide": {
53
+ "title": "Human Evolution",
54
+ "bullets": [
55
+ "Early Primates",
56
+ "Hominids and Hominins",
57
+ "Australopithecus",
58
+ "Genus Homo Emerges",
59
+ "Homo erectus and Migration",
60
+ "Neanderthals and Other Archaic Humans",
61
+ "Homo sapiens"
62
+ ]
63
+ }
64
+ }
65
+ },
66
+ {
67
+ "speaker": "Presenter",
68
+ "text": "Our story begins with tree-dwelling primates—small mammals with forward-facing eyes and grasping hands. These ancestors lived in forests and evolved traits useful for climbing and visual depth perception.",
69
+ "image": {
70
+ "type": "markdown",
71
+ "markdown": [
72
+ "# Markdown Table Example",
73
+ "| Item | In Stock | Price |",
74
+ "| :---------------- | :------: | ----: |",
75
+ "| Python Hat | True | 23.99 |",
76
+ "| SQL Hat | True | 23.99 |",
77
+ "| Codecademy Tee | False | 19.99 |",
78
+ "| Codecademy Hoodie | False | 42.99 |"
79
+ ]
80
+ }
81
+ },
82
+ {
83
+ "speaker": "Presenter",
84
+ "text": "Our story begins with tree-dwelling primates—small mammals with forward-facing eyes and grasping hands. These ancestors lived in forests and evolved traits useful for climbing and visual depth perception.",
85
+ "imagePrompt": "tree-dwelling primates with forward-facing eyes in a jungle."
86
+ }
87
+ ]
88
+ }
89
+ }
@@ -0,0 +1,135 @@
1
+ {
2
+ "title": "Children Book",
3
+ "description": "Template for children book.",
4
+ "systemPrompt": "Please generate a script for a children book on the topic provided by the user. Each page (=beat) must haven an image prompt appropriate for the text.",
5
+ "script": {
6
+ "$mulmocast": {
7
+ "version": "1.0",
8
+ "credit": "closing"
9
+ },
10
+ "title": "桃太郎",
11
+ "canvasSize": {
12
+ "width": 1536,
13
+ "height": 1024
14
+ },
15
+ "imageParams": {
16
+ "style": "A hand-drawn style illustration with a warm, nostalgic atmosphere. The background is rich with natural scenery—lush forests, cloudy skies, and traditional Japanese architecture. Characters have expressive eyes, soft facial features, and are portrayed with gentle lighting and subtle shading. The color palette is muted yet vivid, using earthy tones and watercolor-like textures. The overall scene feels magical and peaceful, with a sense of quiet wonder and emotional depth, reminiscent of classic 1980s and 1990s Japanese animation.",
17
+ "model": "gpt-image-1",
18
+ "size": "1536x1024"
19
+ },
20
+ "speechParams": {
21
+ "speakers": {
22
+ "Presenter": {
23
+ "voiceId": "shimmer",
24
+ "displayName": {
25
+ "en": "Presenter",
26
+ "ja": "語り手"
27
+ }
28
+ }
29
+ }
30
+ },
31
+ "lang": "ja",
32
+ "beats": [
33
+ {
34
+ "speaker": "Presenter",
35
+ "text": "むかしむかし、あるところにおじいさんとおばあさんが住んでいました。おじいさんは山へ芝刈りに、おばあさんは川へ洗濯に行きました。",
36
+ "imagePrompt": "藁葺き屋根の古い日本家屋。近くには清らかな川が流れ、裏には緑豊かな山がある。おじいさんは鎌を持って山へ向かい、おばあさんは洗濯かごを持って川へ向かっている。春の穏やかな日差しが風景を照らしている。"
37
+ },
38
+ {
39
+ "speaker": "Presenter",
40
+ "text": "おばあさんが川で洗濯をしていると、上流から大きな桃が流れてきました。「まあ、なんて大きな桃でしょう」とおばあさんは驚きました。",
41
+ "imagePrompt": "川で洗濯するおばあさん。川面に映る青空と白い雲。上流から流れてくる異様に大きくて鮮やかな赤い桃。驚いた表情でそれを見つめるおばあさん。周りには洗濯物と石。"
42
+ },
43
+ {
44
+ "speaker": "Presenter",
45
+ "text": "おばあさんはその桃を持ち帰り、「おじいさん、大きな桃を見つけましたよ」と言いました。二人が桃を切ろうとすると、中から元気な男の子が生まれました。",
46
+ "imagePrompt": "家の中、赤ん坊を高く抱き上げて、驚きと喜びの表情を浮かべる老夫婦。"
47
+ },
48
+ {
49
+ "speaker": "Presenter",
50
+ "text": "二人は男の子を「桃太郎」と名付けて、大切に育てました。桃太郎はすくすくと成長し、とても強い子になりました。",
51
+ "imagePrompt": "時間の経過を示す4コマの連続画像。最初は赤ちゃん、次に幼児、そして少年、最後に若い男性へと成長する桃太郎。各段階でおじいさんとおばあさんが愛情深く見守っている。最後の画像では、たくましく成長した桃太郎が木を持ち上げたり、重い石を運んだりして力の強さを示している。"
52
+ },
53
+ {
54
+ "speaker": "Presenter",
55
+ "text": "ある日、鬼が島から来た鬼たちが村を荒らしているという話を聞いた桃太郎は、おじいさんとおばあさんに「鬼退治に行きます」と告げました。",
56
+ "imagePrompt": "家の中の桃太郎、おじいさんとおばあさん。窓の外では村人たちが恐怖の表情で逃げ回り、遠くには炎と煙が見える。決意に満ちた表情の桃太郎が立ち上がり、おじいさんとおばあさんに語りかけている。憂慮と誇りの入り混じった表情の老夫婦。"
57
+ },
58
+ {
59
+ "speaker": "Presenter",
60
+ "text": "おばあさんは桃太郎のために、日本一のきびだんごを作ってくれました。おじいさんは立派な刀と着物をくれました。",
61
+ "imagePrompt": "家の中。おばあさんが台所できびだんごを作り、おじいさんが桐箱から刀と鮮やかな着物を取り出している。準備を整える桃太郎。テーブルの上には小さな布包みにきびだんごが包まれている。朝日が障子を通して部屋を温かく照らしている。"
62
+ },
63
+ {
64
+ "speaker": "Presenter",
65
+ "text": "「いってきます」と言って、桃太郎はきびだんごを持って、鬼が島へ向かいました。",
66
+ "imagePrompt": "家の前で出発する桃太郎。腰にはきびだんごの入った袋と刀、背中には小さな旗。見送るおじいさんとおばあさん、そして村人たち。桃太郎は自信に満ちた表情で前方を見つめている。朝霧の中、道は山々へと続いている。"
67
+ },
68
+ {
69
+ "speaker": "Presenter",
70
+ "text": "道中、桃太郎は犬に出会いました。「桃太郎さん、桃太郎さん、お腰につけたきびだんご、一つわたしに下さいな」と犬は言いました。",
71
+ "imagePrompt": "山道を進む桃太郎。横には大きな茶色の犬が立っている。犬は尾を振り、期待を込めた表情で桃太郎を見上げている。周りには春の花と緑豊かな自然。桃太郎は犬に微笑みかけている。"
72
+ },
73
+ {
74
+ "speaker": "Presenter",
75
+ "text": "「よし、一つあげよう。その代わり家来になるんだよ」と桃太郎は言いました。犬は喜んできびだんごを食べ、桃太郎の家来になりました。",
76
+ "imagePrompt": "桃太郎がきびだんごを犬に渡している様子。犬が嬉しそうにきびだんごを食べている。桃太郎の表情は優しく頼もしい。背景には山と川、遠くには鬼が島を思わせる遠景。"
77
+ },
78
+ {
79
+ "speaker": "Presenter",
80
+ "text": "次に、桃太郎と犬は猿に出会いました。猿もきびだんごと引き換えに、桃太郎の家来になりました。",
81
+ "imagePrompt": "森の中の道。桃太郎と犬が木にとまる猿と話している。猿は好奇心いっぱいの表情で桃太郎の手にあるきびだんごを見ている。周りには色とりどりの木々と花。犬は猿を友好的に見上げている。"
82
+ },
83
+ {
84
+ "speaker": "Presenter",
85
+ "text": "さらに進むと、今度はキジに出会いました。キジもきびだんごをもらい、桃太郎の家来になりました。",
86
+ "imagePrompt": "山の開けた場所。空高く舞うカラフルなキジが桃太郎たちに近づいてきている。地面には桃太郎、犬、猿が立っており、空を見上げている。キジは美しい羽を広げ、桃太郎のきびだんごに目を向けている。背景には雄大な山々と澄んだ青空。"
87
+ },
88
+ {
89
+ "speaker": "Presenter",
90
+ "text": "こうして桃太郎は、犬、猿、キジを家来にして、いよいよ鬼が島へと向かいました。",
91
+ "imagePrompt": "海に浮かぶ鬼が島に向かう小さな船。船の上には桃太郎、犬、猿、キジが乗っている。桃太郎は立って指揮を取り、犬は船の前方を見据え、猿は帆を操作し、キジは空から見張りをしている。荒々しい波と暗雲が立ち込める中、島へと近づく彼らの姿。島には険しい岩山と不気味な城が見える。"
92
+ },
93
+ {
94
+ "speaker": "Presenter",
95
+ "text": "鬼が島に着くと、そこには大きな門がありました。キジが飛んで様子を見ると、中では鬼たちが宴会をしていました。",
96
+ "imagePrompt": "鬼ヶ島の大きな赤い門。門の上空を飛ぶキジ。門の向こう側では、様々な色の鬼たちが酒を飲み、踊り、騒いでいる様子が見える。鬼の中には角が1本、2本、3本のものなど様々。宴会場の周りには盗んできた宝物が山積みになっている。門の手前には桃太郎、犬、猿が隠れて様子をうかがっている。"
97
+ },
98
+ {
99
+ "speaker": "Presenter",
100
+ "text": "「よーし、みんな準備はいいか。今から鬼退治だ!」と桃太郎は言いました。",
101
+ "imagePrompt": "鬼ヶ島の入り口近く、岩陰に隠れた桃太郎と家来たち。桃太郎は刀を抜き、決意に満ちた表情で仲間たちに語りかけている。犬は牙をむき、猿は棒を構え、キジは鋭い嘴を見せて戦う準備をしている。全員が真剣な表情で桃太郎の言葉に耳を傾けている。背景には鬼の城が不気味にそびえ立っている。"
102
+ },
103
+ {
104
+ "speaker": "Presenter",
105
+ "text": "桃太郎たちは勇敢に戦いました。犬は鬼の足に噛みつき、猿は鬼の髪を引っ張り、キジは鬼の目をつついて攻撃しました。",
106
+ "imagePrompt": "鬼ヶ島の城の中での激しい戦闘シーン。様々な色の鬼たちが驚きと怒りの表情で戦っている。犬は赤鬼の足に噛みついて倒し、猿は青鬼の髪を引っ張って混乱させ、キジは緑鬼の目をつついている。中央では桃太郎が刀を振るい、黄色い鬼と対峙している。背景には他の鬼たちも逃げ惑う姿がある。戦いの熱気と混乱が画面いっぱいに広がっている。"
107
+ },
108
+ {
109
+ "speaker": "Presenter",
110
+ "text": "そして桃太郎は鬼の大将に向かって行きました。激しい戦いの末、桃太郎は鬼の大将を倒しました。",
111
+ "imagePrompt": "城の奥、豪華な部屋での桃太郎と鬼の大将との一騎打ち。鬼の大将は巨大で、赤い肌に金色の兜と鉄の棍棒を持っている。桃太郎は小さいながらも勇敢に刀を構えて対峙している。部屋の周りには宝物が散らばり、窓からは戦いを見守る家来たちの姿が見える。決定的な一撃を加えようとする桃太郎と、驚きの表情を浮かべる鬼の大将。"
112
+ },
113
+ {
114
+ "speaker": "Presenter",
115
+ "text": "「もう悪いことはしません。命だけはお助けください」と鬼たちは降参しました。そして村から盗んだ宝物をすべて差し出しました。",
116
+ "imagePrompt": "床に頭を下げて土下座する鬼の大将と鬼たち。勝利した桃太郎が堂々と立ち、家来たちがその横に誇らしげに並んでいる。鬼たちの前には金銀財宝、布、米俵など盗んだ宝物が山と積まれている。鬼たちは恐れと後悔の表情を浮かべている。桃太郎の表情は厳しいながらも慈悲深さを感じさせる。"
117
+ },
118
+ {
119
+ "speaker": "Presenter",
120
+ "text": "桃太郎と家来たちは宝物を持って村に帰りました。村人たちは大喜びで彼らを迎えました。",
121
+ "imagePrompt": "村に凱旋する桃太郎と家来たち。宝物を運ぶ犬、猿、キジ。桃太郎は誇らしげに村人たちに手を振っている。老若男女の村人たちが道の両側に集まり、喜びの表情で花や旗を振って迎えている。おじいさんとおばあさんも最前列で涙を流しながら桃太郎の帰りを待っている。春の明るい日差しが村全体を照らしている。"
122
+ },
123
+ {
124
+ "speaker": "Presenter",
125
+ "text": "おじいさんとおばあさんは桃太郎の無事な帰りを喜び、抱きしめました。そして村はもう二度と鬼に襲われることはありませんでした。",
126
+ "imagePrompt": "家の前でおじいさんとおばあさんが桃太郎を抱きしめている感動的な場面。喜びの涙を流すおじいさんとおばあさん。犬、猿、キジも幸せそうに見守っている。周りには村人たちが集まり、祝福している。家の前には宝物の一部が置かれ、背景には平和な村の風景が広がっている。夕日が温かな光を投げかけ、晴れやかな雰囲気を作り出している。"
127
+ },
128
+ {
129
+ "speaker": "Presenter",
130
+ "text": "こうして桃太郎とおじいさんとおばあさん、そして家来たちは幸せに暮らしました。めでたし、めでたし。",
131
+ "imagePrompt": "時が経ち、平和になった村の風景。桃太郎の家では、おじいさんとおばあさんが縁側でお茶を飲んでいる。庭では成長した桃太郎が犬、猿、キジと一緒に楽しそうに過ごしている。背景には実りある田んぼと平和な村の様子。桃の木が花を咲かせ、その下で皆が笑顔で暮らしている。夕暮れの優しい光が全体を包み込み、物語の幸せな結末を象徴している。"
132
+ }
133
+ ]
134
+ }
135
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "title": "Generic",
3
+ "description": "Generic. No template.",
4
+ "systemPrompt": "Please generate a podcast script based on the topic provided by the user."
5
+ }
@@ -0,0 +1,123 @@
1
+ {
2
+ "title": "Student and Teacher",
3
+ "description": "Interactive discussion between a student and teacher",
4
+ "systemPrompt": "この件について、内容全てを高校生にも分かるように、太郎くん(Student)と先生(Teacher)の会話、という形の台本をArtifactとして作って。ただし要点はしっかりと押さえて。以下に別のトピックに関するサンプルを貼り付けます。このJSONフォーマットに従って。",
5
+ "script": {
6
+ "$mulmocast": {
7
+ "version": "1.0",
8
+ "credit": "closing"
9
+ },
10
+ "title": "韓国の戒厳令とその日本への影響",
11
+ "description": "韓国で最近発令された戒厳令とその可能性のある影響について、また日本の憲法に関する考慮事項との類似点を含めた洞察に満ちた議論。",
12
+ "lang": "ja",
13
+ "speechParams": {
14
+ "provider": "nijivoice",
15
+ "speakers": {
16
+ "Announcer": {
17
+ "displayName": {
18
+ "ja": "アナウンサー"
19
+ },
20
+ "voiceId": "afd7df65-0fdc-4d31-ae8b-a29f0f5eed62"
21
+ },
22
+ "Student": {
23
+ "displayName": {
24
+ "ja": "生徒"
25
+ },
26
+ "voiceId": "a7619e48-bf6a-4f9f-843f-40485651257f"
27
+ },
28
+ "Teacher": {
29
+ "displayName": {
30
+ "ja": "先生"
31
+ },
32
+ "voiceId": "bc06c63f-fef6-43b6-92f7-67f919bd5dae"
33
+ }
34
+ }
35
+ },
36
+ "beats": [
37
+ {
38
+ "speaker": "Announcer",
39
+ "text": "今日は、韓国で起きた戒厳令について、太郎くんが先生に聞きます。"
40
+ },
41
+ {
42
+ "speaker": "Student",
43
+ "text": "先生、今日は韓国で起きた戒厳令のことを教えてもらえますか?"
44
+ },
45
+ {
46
+ "speaker": "Teacher",
47
+ "text": "もちろんだよ、太郎くん。韓国で最近、大統領が「戒厳令」っていうのを突然宣言したんだ。"
48
+ },
49
+ {
50
+ "speaker": "Student",
51
+ "text": "戒厳令ってなんですか?"
52
+ },
53
+ {
54
+ "speaker": "Teacher",
55
+ "text": "簡単に言うと、国がすごく危ない状態にあるとき、軍隊を使って人々の自由を制限するためのものなんだ。たとえば、政治活動を禁止したり、人の集まりを取り締まったりするんだよ。"
56
+ },
57
+ {
58
+ "speaker": "Student",
59
+ "text": "それって怖いですね。なんでそんなことをしたんですか?"
60
+ },
61
+ {
62
+ "speaker": "Teacher",
63
+ "text": "大統領は「国会がうまく機能していないから」と言っていたけど、実際には自分の立場を守るために使ったように見えるんだ。それで、軍隊が国会に突入して、議員たちを捕まえようとしたんだ。"
64
+ },
65
+ {
66
+ "speaker": "Student",
67
+ "text": "ええっ!?国会議員を捕まえようとするなんて、すごく危ないことじゃないですか。"
68
+ },
69
+ {
70
+ "speaker": "Teacher",
71
+ "text": "その通りだよ。もし軍隊が国会を占拠していたら、国会で戒厳令を解除することもできなかったかもしれない。つまり、大統領がずっと自分の好きなように国を支配できるようになってしまうんだ。"
72
+ },
73
+ {
74
+ "speaker": "Student",
75
+ "text": "韓国ではどうなったんですか?"
76
+ },
77
+ {
78
+ "speaker": "Teacher",
79
+ "text": "幸い、野党の議員や市民たちが急いで集まって抗議して、6時間後に戒厳令は解除されたんだ。でも、ほんの少しの違いで、韓国の民主主義が大きく傷つけられるところだったんだよ。"
80
+ },
81
+ {
82
+ "speaker": "Student",
83
+ "text": "それは大変なことですね…。日本ではそんなこと起きないんですか?"
84
+ },
85
+ {
86
+ "speaker": "Teacher",
87
+ "text": "実はね、今、日本でも似たような話があるんだよ。自民党が「緊急事態宣言」を憲法に追加しようとしているんだ。"
88
+ },
89
+ {
90
+ "speaker": "Student",
91
+ "text": "緊急事態宣言って、韓国の戒厳令と同じようなものなんですか?"
92
+ },
93
+ {
94
+ "speaker": "Teacher",
95
+ "text": "似ている部分があるね。たとえば、総理大臣が「社会秩序の混乱の危険があるから」と言えば、特別な権限を使って国を動かすことができるんだ。法律と同じ力を持つ命令を出したり、地方自治体に指示を出したりすることができるんだよ。"
96
+ },
97
+ {
98
+ "speaker": "Student",
99
+ "text": "それって便利そうですけど、なんだか心配です。"
100
+ },
101
+ {
102
+ "speaker": "Teacher",
103
+ "text": "そうだね。もちろん、緊急時には素早い対応が必要だから便利な面もあるけど、その権限が濫用されると、とても危険なんだ。たとえば、総理大臣が自分に都合のいいように国を動かしたり、国民の自由を奪ったりすることができるようになってしまうかもしれない。"
104
+ },
105
+ {
106
+ "speaker": "Student",
107
+ "text": "韓国みたいに、軍隊が政治に口を出してくることもあり得るんですか?"
108
+ },
109
+ {
110
+ "speaker": "Teacher",
111
+ "text": "完全にあり得ないとは言えないからこそ、注意が必要なんだ。私たち国民は、自民党の改憲案が権力の濫用を防ぐための適切な制限を含んでいるのかをしっかり監視し、声を上げることが求められる。民主主義が損なわれるのを防ぐために、私たち一人ひとりが積極的に関心を持つことが大切なんだよ。"
112
+ },
113
+ {
114
+ "speaker": "Student",
115
+ "text": "ありがとうございます。とても良い勉強になりました。"
116
+ },
117
+ {
118
+ "speaker": "Announcer",
119
+ "text": "ご視聴、ありがとうございました。次回の放送もお楽しみに。"
120
+ }
121
+ ]
122
+ }
123
+ }
@@ -0,0 +1,3 @@
1
+ import "dotenv/config";
2
+ import { MulmoStudioContext } from "../types";
3
+ export declare const audio: (context: MulmoStudioContext, concurrency: number) => Promise<void>;
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.audio = void 0;
40
+ require("dotenv/config");
41
+ const graphai_1 = require("graphai");
42
+ const agents = __importStar(require("@graphai/vanilla"));
43
+ const tts_nijivoice_agent_1 = __importDefault(require("../agents/tts_nijivoice_agent"));
44
+ const add_bgm_agent_1 = __importDefault(require("../agents/add_bgm_agent"));
45
+ const combine_audio_files_agent_1 = __importDefault(require("../agents/combine_audio_files_agent"));
46
+ const tts_openai_agent_1 = __importDefault(require("../agents/tts_openai_agent"));
47
+ const vanilla_node_agents_1 = require("@graphai/vanilla_node_agents");
48
+ const methods_1 = require("../methods");
49
+ const filters_1 = require("../utils/filters");
50
+ const file_1 = require("../utils/file");
51
+ // const rion_takanashi_voice = "b9277ce3-ba1c-4f6f-9a65-c05ca102ded0"; // たかなし りおん
52
+ // const ben_carter_voice = "bc06c63f-fef6-43b6-92f7-67f919bd5dae"; // ベン・カーター
53
+ const graph_tts = {
54
+ nodes: {
55
+ preprocessor: {
56
+ agent: (namedInputs) => {
57
+ const { beat, script, speakers } = namedInputs;
58
+ return {
59
+ voiceId: speakers[beat.speaker].voiceId,
60
+ speechOptions: methods_1.MulmoScriptMethods.getSpeechOptions(script, beat),
61
+ };
62
+ },
63
+ inputs: {
64
+ beat: ":beat",
65
+ script: ":script",
66
+ speakers: ":script.speechParams.speakers",
67
+ },
68
+ },
69
+ ttsAgent: {
70
+ agent: (namedInputs) => {
71
+ if (namedInputs.provider === "nijivoice") {
72
+ return "ttsNijivoiceAgent";
73
+ }
74
+ return "ttsOpenaiAgent";
75
+ },
76
+ inputs: {
77
+ provider: ":script.speechParams.provider",
78
+ },
79
+ },
80
+ tts: {
81
+ unless: ":beat.audio",
82
+ agent: ":ttsAgent",
83
+ inputs: {
84
+ text: ":beat.text",
85
+ file: "${:scratchpadDirPath}/${:beat.audioFile}.mp3", // TODO
86
+ },
87
+ params: {
88
+ voice: ":preprocessor.voiceId",
89
+ speed: ":preprocessor.speechOptions.speed",
90
+ instructions: ":preprocessor.speechOptions.instruction",
91
+ },
92
+ },
93
+ },
94
+ };
95
+ const graph_data = {
96
+ version: 0.5,
97
+ concurrency: 8,
98
+ nodes: {
99
+ context: {},
100
+ outputBGMFilePath: {},
101
+ outputAudioFilePath: {},
102
+ outputStudioFilePath: {},
103
+ scratchpadDirPath: {},
104
+ map: {
105
+ agent: "mapAgent",
106
+ inputs: { rows: ":context.studio.beats", script: ":context.studio.script", scratchpadDirPath: ":scratchpadDirPath" },
107
+ params: {
108
+ rowKey: "beat",
109
+ },
110
+ graph: graph_tts,
111
+ },
112
+ combineFiles: {
113
+ agent: "combineAudioFilesAgent",
114
+ inputs: {
115
+ map: ":map",
116
+ context: ":context",
117
+ combinedFileName: ":outputAudioFilePath",
118
+ scratchpadDirPath: ":scratchpadDirPath",
119
+ },
120
+ isResult: true,
121
+ },
122
+ fileWrite: {
123
+ agent: "fileWriteAgent",
124
+ inputs: {
125
+ file: ":outputStudioFilePath",
126
+ text: ":combineFiles.studio.toJSON()",
127
+ },
128
+ },
129
+ addBGM: {
130
+ agent: "addBGMAgent",
131
+ params: {
132
+ musicFile: process.env.PATH_BGM ?? file_1.defaultBGMPath,
133
+ },
134
+ inputs: {
135
+ wait: ":combineFiles",
136
+ voiceFile: ":outputAudioFilePath",
137
+ outputFile: ":outputBGMFilePath",
138
+ script: ":context.studio.script",
139
+ },
140
+ isResult: true,
141
+ },
142
+ title: {
143
+ agent: "copyAgent",
144
+ params: {
145
+ namedKey: "title",
146
+ },
147
+ inputs: {
148
+ title: "\n${:context.studio.script.title}\n\n${:context.studio.script.description}\nReference: ${:context.studio.script.reference}\n",
149
+ waitFor: ":addBGM",
150
+ },
151
+ },
152
+ },
153
+ };
154
+ const agentFilters = [
155
+ {
156
+ name: "fileCacheAgentFilter",
157
+ agent: filters_1.fileCacheAgentFilter,
158
+ nodeIds: ["tts"],
159
+ },
160
+ ];
161
+ const audio = async (context, concurrency) => {
162
+ const { studio, fileDirs } = context;
163
+ const { outDirPath, scratchpadDirPath } = fileDirs;
164
+ const outputBGMFilePath = (0, file_1.getOutputBGMFilePath)(outDirPath, studio.filename);
165
+ const outputAudioFilePath = (0, file_1.getOutputAudioFilePath)(outDirPath, studio.filename);
166
+ const outputStudioFilePath = (0, file_1.getOutputStudioFilePath)(outDirPath, studio.filename);
167
+ (0, file_1.mkdir)(outDirPath);
168
+ (0, file_1.mkdir)(scratchpadDirPath);
169
+ graph_data.concurrency = concurrency;
170
+ const graph = new graphai_1.GraphAI(graph_data, {
171
+ ...agents,
172
+ fileWriteAgent: vanilla_node_agents_1.fileWriteAgent,
173
+ ttsOpenaiAgent: tts_openai_agent_1.default,
174
+ ttsNijivoiceAgent: tts_nijivoice_agent_1.default,
175
+ addBGMAgent: add_bgm_agent_1.default,
176
+ combineAudioFilesAgent: combine_audio_files_agent_1.default,
177
+ }, { agentFilters });
178
+ graph.injectValue("context", context);
179
+ graph.injectValue("outputBGMFilePath", outputBGMFilePath);
180
+ graph.injectValue("outputAudioFilePath", outputAudioFilePath);
181
+ graph.injectValue("outputStudioFilePath", outputStudioFilePath);
182
+ graph.injectValue("scratchpadDirPath", scratchpadDirPath);
183
+ await graph.run();
184
+ (0, file_1.writingMessage)(outputAudioFilePath);
185
+ };
186
+ exports.audio = audio;
@@ -0,0 +1,2 @@
1
+ import { MulmoStudioContext } from "../types";
2
+ export declare const images: (context: MulmoStudioContext) => Promise<void>;