gstvideo.lua 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #! /usr/bin/env lua
  2. --
  3. -- Sample GStreamer application, based on public Vala GStreamer Video
  4. -- Example (http://live.gnome.org/Vala/GStreamerSample)
  5. --
  6. local lgi = require 'lgi'
  7. local GLib = lgi.GLib
  8. local Gtk = lgi.Gtk
  9. local GdkX11 = lgi.GdkX11
  10. local Gst = lgi.Gst
  11. if tonumber(Gst._version) >= 1.0 then
  12. local GstVideo = lgi.GstVideo
  13. end
  14. local app = Gtk.Application { application_id = 'org.lgi.samples.gstvideo' }
  15. local window = Gtk.Window {
  16. title = "LGI Based Video Player",
  17. Gtk.Box {
  18. orientation = 'VERTICAL',
  19. Gtk.DrawingArea {
  20. id = 'video',
  21. expand = true,
  22. width = 300,
  23. height = 150,
  24. },
  25. Gtk.ButtonBox {
  26. orientation = 'HORIZONTAL',
  27. Gtk.Button {
  28. id = 'play',
  29. use_stock = true,
  30. label = Gtk.STOCK_MEDIA_PLAY,
  31. },
  32. Gtk.Button {
  33. id = 'stop',
  34. use_stock = true,
  35. sensitive = false,
  36. label = Gtk.STOCK_MEDIA_STOP,
  37. },
  38. Gtk.Button {
  39. id = 'quit',
  40. use_stock = true,
  41. label = Gtk.STOCK_QUIT,
  42. },
  43. },
  44. }
  45. }
  46. function window.child.quit:on_clicked()
  47. window:destroy()
  48. end
  49. local pipeline = Gst.Pipeline.new('mypipeline')
  50. local src = Gst.ElementFactory.make('autovideosrc', 'videosrc')
  51. local colorspace = Gst.ElementFactory.make('videoconvert', 'colorspace')
  52. or Gst.ElementFactory.make('ffmpegcolorspace', 'colorspace')
  53. local scale = Gst.ElementFactory.make('videoscale', 'scale')
  54. local rate = Gst.ElementFactory.make('videorate', 'rate')
  55. local sink = Gst.ElementFactory.make('xvimagesink', 'sink')
  56. pipeline:add_many(src, colorspace, scale, rate, sink)
  57. src:link_many(colorspace, scale, rate, sink)
  58. function window.child.play:on_clicked()
  59. pipeline.state = 'PLAYING'
  60. end
  61. function window.child.stop:on_clicked()
  62. pipeline.state = 'PAUSED'
  63. end
  64. local function bus_callback(bus, message)
  65. if message.type.ERROR then
  66. print('Error:', message:parse_error().message)
  67. Gtk.main_quit()
  68. end
  69. if message.type.EOS then
  70. print 'end of stream'
  71. end
  72. if message.type.STATE_CHANGED then
  73. local old, new, pending = message:parse_state_changed()
  74. print(string.format('state changed: %s->%s:%s', old, new, pending))
  75. -- Set up sensitive state on buttons according to current state.
  76. -- Note that this is forwarded to mainloop, because bus callback
  77. -- can be called in some side thread and Gtk might not like to
  78. -- be controlled from other than main thread on some platforms.
  79. GLib.idle_add(GLib.PRIORITY_DEFAULT, function()
  80. window.child.play.sensitive = (new ~= 'PLAYING')
  81. window.child.stop.sensitive = (new == 'PLAYING')
  82. return GLib.SOURCE_REMOVE
  83. end)
  84. end
  85. if message.type.TAG then
  86. message:parse_tag():foreach(
  87. function(list, tag)
  88. print(('tag: %s = %s'):format(tag, tostring(list:get(tag))))
  89. end)
  90. end
  91. return true
  92. end
  93. function window.child.video:on_realize()
  94. -- Retarget video output to the drawingarea.
  95. sink:set_window_handle(self.window:get_xid())
  96. end
  97. function app:on_activate()
  98. window.application = app
  99. pipeline.bus:add_watch(GLib.PRIORITY_DEFAULT, bus_callback)
  100. window:show_all()
  101. end
  102. app:run { arg[0], ... }
  103. -- Must always set the pipeline to NULL before disposing it
  104. pipeline.state = 'NULL'