YouTubeの動画を検索して表示するアプリケーション(完成版)

科学に関する動画をYouTubeから検索して、手軽に見られるようなアプリケーションを作成した。YouTube APIの使い方に触れるために即席で作ったものなので、まだまだ改良の余地はある。

最初に好きなジャンルを選んで検索ボタンを押すと、検索結果のテーブルが作成される。そのテーブルの中から動画を選んで、番号を指定し再生ボタンを押すことで動画が再生される。

  • このアプリケーションについて
    • wxPythonGUIを作成
    • Google Data LibraryのYouTube APIを使用
    • 動画の再生はブラウザ上で行う
    • 動作時はネットに繋がっていること
    • Pythonソースコード2つから成る。_main_tree.pyとMainFrame.py
    • 実行は、_main_tree.pyの方をダブルクリックする
    • wxPythonGoogle Data Libraryを事前にインストールしておくことが必要
  • 気になっている点
    • 検索結果の動画数が常に25個になるが、この数を制御する方法はあるか。
  • 実行例
    • _main_tree.pyをアプリケーションの起動画面は以下の通り。

    • ジャンルから”宇宙”を選んで、”このジャンルの動画を検索する”ボタンを押す。すると下の図のようにテーブルに検索された動画のタイトルと再生時間が表示される。

    • テーブルから見たい動画を選び、その番号をスピンコントロールで指定する。下の図では8番目の動画を選択した。その横の”動画を再生する”ボタンを押すとブラウザが起動する。

    • ブラウザが起動した時点で、動画は再生可能な状態になっている。

以下、Pythonソースコード

#                      _main_tree.py
# ----------------------------------------------------------------------
import os, sys
import wx

import MainFrame

class Application(wx.App):
    def OnInit(self):
        frame = MainFrame.MainFrame(None, -1)
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

def main():
    import time

    app = Application(0)
    print u"info> このアプリケーションの起動時刻は %sです。" % time.ctime(time.time())
    print u"info> 起動ディレクトリは %sです。" % os.getcwd()
    app.MainLoop()
#!/bin/env python
# coding: utf-8 
#                        MainFrame.py
#----------------------------------------------------------------------------
import wx
import wx.grid
import gdata.youtube
import gdata.youtube.service
import webbrowser

class MainFrame(wx.Frame):       
    def __init__(self, id, title):
        width, height = 600,400              # 外枠を作成
        wx.Frame.__init__(self, id, title=u"Enjoy science videos on YouTube!!",
                          size=wx.Size(width, height))
        Pan = wx.Panel(self, -1)

    # 検索結果を表示するテーブルを作成
        self.table = DataTable(Pan)     
    # 各コントロールを定義
        self.RBox = wx.RadioBox(Pan, -1, u"ジャンルの選択",
                    choices=[u"宇宙", u"物理", u"化学", u"生物", u"コンピュータ"])
        self.Btn = wx.Button(Pan, -1, u"このジャンルの動画を検索する")
        self.Btn2= wx.Button(Pan, -1, u"番目の動画を再生する")
        self.StTxt = wx.StaticText(Pan, -1, u"上のテーブルで")
        self.Spn = wx.SpinCtrl(Pan, -1, '1', min=1, max=25)

        self.Btn.Bind(wx.EVT_BUTTON, self.SearchBtn)
        self.Btn2.Bind(wx.EVT_BUTTON, self.PlayBtn)
    # サイザーできれいに並べる
        vsizer = wx.BoxSizer(wx.VERTICAL)
        hsizer = wx.BoxSizer(wx.HORIZONTAL)
        vsizer.Add(self.RBox, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        vsizer.Add(self.Btn,  0, wx.ALIGN_LEFT|wx.ALL, 5)
        vsizer.Add(self.table,0, wx.ALIGN_LEFT|wx.ALL, 5)
        hsizer.Add(self.StTxt,0, wx.ALIGN_LEFT|wx.ALL, 5)
        hsizer.Add(self.Spn,  0, wx.ALIGN_LEFT|wx.ALL, 5)
        hsizer.Add(self.Btn2, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        vsizer.Add(hsizer, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        Pan.SetSizer(vsizer)
        vsizer.Fit(Pan)

    def SearchBtn(self, event):
    # 検索ボタンを押したときの処理
        self.Skind = self.RBox.GetSelection()
        RegionList = ["Space", "Physics", "Chemistry", "Biology", "Computer"]
        url = "http://gdata.youtube.com/feeds/api/videos?vq=Science+%s" %\
        RegionList[self.Skind]

    # YouTubeからfeedを取得
        yt = gdata.youtube.service.YouTubeService()
        feed = yt.GetYouTubeVideoFeed(url)

        self.table.VNumber = 0
        self.table.TitleList = []
        self.table.VpageList = []
        self.table.DtimeList = []

    # entry毎の必要な情報を保存
        for entry in feed.entry:
            self.table.VNumber += 1
            self.table.TitleList.append(entry.media.title.text)
            self.table.VpageList.append(entry.GetSwfUrl())
            self.table.DtimeList.append(entry.media.duration.seconds)
    # 検索結果のタイトルと再生時間をテーブルに表示
        self.table.UpdateList(self.table.VNumber)

    def PlayBtn(self, event):
    # 再生ボタンを押したときの処理
        Vnumber = self.Spn.GetValue()
    # 動画のURLにアクセス。ブラウザで表示
        webbrowser.open(self.table.VpageList[Vnumber-1])

class DataTable(wx.grid.Grid):
  # 検索結果の情報を一覧表示するテーブル
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1)

        self.InitRow = 10
        self.CreateGrid(self.InitRow, 2)
        self.SetColLabelValue(0, u"動画のタイトル")
        self.SetColLabelValue(1, u"再生時間[秒]")
        self.SetColSize(0, 400)
        self.SetColSize(1, 80)
# タイトルをクリックするだけで再生できるようにしようとしたが
# うまくいかなかったのでやめる
#        self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnSelect)

        self.VNumber = 0
        self.TitleList = []
        self.VpageList = []
        self.DtimeList = []

    def UpdateList(self, RowNum):
  # 検索結果をリストに表示する
        if RowNum > self.InitRow:
            self.AppendRows(RowNum-self.InitRow)
            self.InitRow = RowNum

        for Row in xrange(RowNum):
            self.SetCellValue(Row, 0, self.TitleList[Row])
            self.SetCellValue(Row, 1, self.DtimeList[Row])

    def OnSelect(self, event):
  # 使わない
        Row = event.GetRow()
        print Row