Media.PlayVideo

Hello,
I’m making a vertical game in Corona SDK but when I try to play a Video with the media.playVideo API all it does is perform the listener as if the video as ended when it never even played.

I’m using corona on windows can this be the cause for it not to show on my pc?

Hello and welcome to the community!

Please have a look at:

If you can get by with it, you might try native.newWebView with a local link.

You’re right about the issue on Windows. If Theora is okay, I’ve got a plugin for that, but so far only for desktop. (It’s just sort of a pain setting up the projects, so for more targets I haven’t.)

In your build settings plugins, you can add {["plugin.theora"] = { publisherId = "com.xibalbastudios" }.

I have a couple people using it, and one of them said I could use a project he put together, so here it is:

main.lua:

-----------------------------------------------------------------------------------------
--
-- main.lua
--
-----------------------------------------------------------------------------------------

-- Your code here

local video = require('video')

local scene = display.newGroup()

local x, y = display.contentCenterX, display.contentCenterY
local w, h = 480, 270
local filename = 'media/video.ogv'
local duration = 242 -- seconds
local function playbackended(watchedToEnd)
    display.newText(
        {
            x = x,
            y = y,
            fontSize = 30,
            align = 'center',
            font = native.systemFont,
            text = 'Thanks for watching!'
        }
    )
    if watchedToEnd then
        print('You watched to the end, congrats!!! :-)')
    else
        print('You stopped watching in the middle of playback, I guess you didn\'t like the video much :-(')
    end
end

local player = video:new()
player:scaffold(x, y, w, h, filename, duration, playbackended)
player:render(scene)
player:audioMixin('media/audio.mp3')

Runtime:addEventListener('key',
    function(event)
        if event.phase == 'up' then
            if event.keyName == 'space' then
                if not player._isPlaying then
                    player:resume()
                else
                    player:pause()
                end
            elseif event.keyName == 'k' then
                player:play()
            elseif event.keyName == 's' then
                player:stop()
            elseif event.keyName == 'i' then
                for k, v in pairs(player:info()) do
                    print(k, v)
                end
            end
        end
    end
)

and video.lua:

local theora = require('plugin.theora')

-------------------------------------------------

local video = {
    _isPlaying = false
}

function video:new(...)
    local instance = ... or {}
    setmetatable(instance, self)
    self.__index = self
    return instance
end

function video:scaffold(x, y, w, h, filename, duration, playbackended)
    self._duration = duration * 1000
    self._onPlaybackEnded = playbackended
    self._video = theora.decodeFromFile(filename)
    --
    self._container = display.newImageRect(self._video.filename, self._video.baseDir, w, h)
    self._container.x, self._container.y = x, y
    --
    self._registry = {
        function(event) self:_play() end
    }
end

function video:render(sceneGroup)
    sceneGroup:insert(self._container)
end

function video:info()
    return {
        paused = self._video.paused,
        format = self._video.format,
        elapsed = self._video.elapsed,
        hasAudio = self._video.hasAudio,
        hasVideo = self._video.hasVideo,
        availableAudio = self._video.availableAudio,
        availableVideo = self._video.availableVideo
    }
end

function video:audioMixin(filename, channel)
    self._audio = audio.loadStream(filename)
    self._channel = channel or 0
end

function video:_play()
    local now, delta = system.getTimer()
    if self._isPlaying then
        if self._prev then
            delta = now - self._prev
        end
        --
        self._video:Step(delta or 0)
        self._video:invalidate()
        --
        if self._video.elapsed >= self._duration then
            self._watchedToEnd = true -- entire video was watched
            self:stop()
        end
    end
    --
    self._prev = now
end

function video:play()
    if self._isPlaying then return end
    --
    if self._audio then
        self._activeChannel = audio.play(self._audio, {channel = self._channel})
    end
    --
    self._isPlaying = true
    Runtime:addEventListener('enterFrame', self._registry[1])
end

function video:pause()
    if not self._isPlaying then return end
    --
    if self._audio then
        audio.pause(self._activeChannel)
    end
    --
    self._isPlaying = false
    self._video:Pause(true)
end

function video:resume()
    if self._isPlaying then return end
    --
    if self._audio then
        audio.resume(self._activeChannel)
    end
    --
    self._isPlaying = true
    self._video:Pause(false)
end

function video:stop()
    Runtime:removeEventListener('enterFrame', self._registry[1])
    --
    if self._audio then
        audio.stop(self._activeChannel)
        audio.dispose(self._audio)
        self._audio = nil
    end
    --
    self._isPlaying = false
    self._video:Pause(true)
    --
    -- slight delay to avoid a crash that occurs when the video stops after being watched to the end
    -- funnily enough, there are no crashes if the video is stopped midway
    -- anyway a slight delay before calling "self._video:releaseSelf()" fixes the problem
    timer.performWithDelay(100,
        function()
            self._video:releaseSelf() -- culprit
            self._container:removeSelf()
            self._video, self._container = nil, nil
            --
            self._onPlaybackEnded(self._watchedToEnd or false)
        end
    )
end

return video

Obviously some of that, like the filenames and time, need customization. The plugin does not have audio support, but I was told that it played well enough in parallel using Solar’s APIs.

Oh really appreciate it man!
But yeah the issue was only on windows because I built the game into apk and installed it on my phone, the video played perfectly it’s just that it’s kind of a drag to have to build the app just so that you can see if the video has a good aspect ratio, if it’s good quality, etc…