USTREAM.TVのチャット(IRC)のメッセージをプレゼン中のスライド上にニコニコ動画のコメント風に表示するプログラムをVB.NETで作ることを妄想した。
IRCのメッセージ受信については、超絶的にシンプルなコードが載っているサイトがあった。C# IRC Bot。これだけでチャンネルに参加してメッセージ受信ができる。USTREAM.TVではユーザ名とパスワードによるログインが必要だけど簡単に実装できそうという雰囲気はわかる。IRCクライアントは昔にMMO RPGをしてたころ仲間内でお金管理などに使うBOTを作ろうとしたことがあって、そのときは日本語で確かVB.NETで作り方を解説しているサイトがあったような気がするのだけど見つからなかった。
さて、メッセージ表示部分は普通に考えると(?)透明なウィンドウを最前面に表示してメッセージを流すというやり方じゃないのかなと思う。文字の移動をどうやってしようかなーめんどそうだなーと考えたところ、PowerPointのアニメーションでいいんじゃね? IRC部分も含めてひとつのアドインで作れそう。
文字のアニメーションをどうやってするのか書いてみた。
Imports System.Drawing
Imports System.Threading
Imports System.Windows.Forms
Imports Microsoft.Office.Core
Imports Microsoft.Office.Interop.PowerPoint
Public Class ThisAddIn
Private SynchronizeInvoke As System.ComponentModel.ISynchronizeInvoke
Private ActiveSlide As Slide
Private DummyPictureBox As New PictureBox
Private GeneratorThread As Thread
Private Delegate Sub AddMessageDelegate(ByVal message As String)
Private Sub DummyMessageGenerator()
Try
Do
SynchronizeInvoke.Invoke(New AddMessageDelegate(AddressOf AddMessage), New Object() {"真っ赤な誓いいいいいいいいいぃ"})
Thread.Sleep(5000)
Loop
Catch ex As ThreadInterruptedException
' Ignore
End Try
End Sub
Private Sub AddMessage(ByVal message As String)
Dim id = Thread.CurrentThread.ManagedThreadId.ToString
Console.WriteLine("AddMessage: " & id)
Dim font As New System.Drawing.Font("メイリオ", 50.0F)
Dim size = DummyPictureBox.CreateGraphics.MeasureString(Now.ToString, font)
Dim label = ActiveSlide.Shapes.AddLabel(MsoTextOrientation.msoTextOrientationHorizontal, _
-size.Width, 0, size.Width, size.Height)
With label.TextFrame.TextRange
.Font.Shadow = MsoTriState.msoCTrue
.Font.Size = 50.0F
.Font.Name = "メイリオ"
.Font.Color.RGB = RGB(255, 0, 0)
.Text = message
End With
Dim effect = ActiveSlide.TimeLine.MainSequence.AddEffect(label, MsoAnimEffect.msoAnimEffectCrawl)
effect.EffectParameters.Direction = MsoAnimDirection.msoAnimDirectionRight
effect.Timing.TriggerType = MsoAnimTriggerType.msoAnimTriggerWithPrevious
End Sub
Private Sub Application_SlideShowBegin(ByVal Wn As SlideShowWindow) Handles Application.SlideShowBegin
GeneratorThread = New Thread(AddressOf DummyMessageGenerator)
GeneratorThread.Start()
End Sub
Private Sub Application_SlideShowEnd(ByVal Pres As Presentation) Handles Application.SlideShowEnd
GeneratorThread.Interrupt()
End Sub
Private Sub Application_SlideShowNextSlide(ByVal Wn As SlideShowWindow) Handles Application.SlideShowNextSlide
ActiveSlide = Wn.View.Slide
End Sub
Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup
Dim c = New Control
c.CreateControl()
Dim p = c.Handle
SynchronizeInvoke = c
End Sub
End Class
こんな感じかな。メインの部分はAddMessageね。スライドショーを開始するとどんどんアクティブなスライドに左から右へ流れるラベルを追加しているだけ。消す処理などはしていない。IRC処理の代わりにAddMessageを呼ぶダミーのスレッドを作成している。
妄想。ニコニコ動画のようなコマンドは、そこまで実装しなくていいと思うけど、USTREAM.TVのチャットには色選択と太字・斜体・下線の効果を付けることができる。これを利用して
- 色はそのまま反映
- 太字だと大きなフォント
- 下線だと字幕表示
- 斜体は?
という感じかなぁ。
気にならない問題点
- アニメーションがクリックすると省略される(メッセージが消える)。同じ問題で次のスライドに行こうとすると表示中のメッセージを全て消してから、次のスライドに表示途中のメッセージを引き継げない。
- スライドショー以外のときにメッセージが表示できない。
- スライドが編集される。
まぁ、消せちゃっていいんじゃない。スライドショー以外のときはWebページのチャットやIRCクライアントでいいんじゃない。どうでしょ?
VSTOの情報少ないよー。