nooodles-ahh / video_services

A WIP drop-in replacement for Source SDK 2013's video services that plays webms
MIT License
25 stars 5 forks source link

Webm Video Services

A functional work in progress drop-in replacement for Source SDK 2013's video services to play codecs commonly stored in webms. This is based on work from libsimplewebm, AVI Materials for Source and Godot's Webm playback

This is intended for standalone Source engine mods released on Steam. This can be used for standard sourcemods but sound playback will not work out of the box without some additional work.

Rationale

The version of Source provided to modders on Windows and Linux only has support for Bink video playback, which isn't well suited for HD video. There is also the issue of licensing as Bink is a proprietary codec, so despite it being provided with Source you're not actually allowed to use it in mods on Steam unless you acquire a license.

The primary reason for having written this is that at the time of writing I'm a developer for the infamous game Hunt Down the Freeman. The game makes heavy use of cutscenes and as Bink was the only option, that's what was used. This resulted in about 6.6GB of video of accept quality, for an hour's worth of content. The same content encoded using VP9 and Opus only takes up a little over 900MB. So about 13%-16% of the original size for equal or, in most cases, better quality. The only instance of lower quality I noticed was in dark scenes, but that's likely due to the absurd bitrate initially used for the Bink versions.

Support

Video Audio
Codec VP8 VP9 AV1 Vorbis Opus
Supported? :white_check_mark: :white_check_mark: :x: :white_check_mark: :white_check_mark:

I may support AV1 in the future as I have been asked about.

Linux requires SDL 2.0.7 or later. Source SDK Base 2013 MP comes with 2.0.4, you'll need to use something newer, like the one that comes with Steam.

I have no plans to support anything other than Linux and Windows but this may incidentally become usable on other platforms that make use of SDL2.

Encoding compatible webms

To encode a compatiable webm I would recommend using WebmConverter, casually known as WebM for Lazys, as it was specifically made for encoding webms with as little effort as possible. While slower to encode you will probably want to be using VP9 and Opus for the best results, you will also need to ensure that the pixel format is YUV420 as other formats are not currently supported. WebmConverter does this by default, but you need to make sure this is done if you're using another encoding program such as FFmpeg or HandBrake.

Building

TODO

Issues I won't fix/Features I won't implement

Sourcemod usage

On Windows you can create a new DirectSound interface object, see the PlayVideoFileFullScreen method on how you might do that. If you don't need audio or have created a new DirectSound object you load this this version of video services by placing this block of code in CHLClient::Init. This can go anywhere after all the interfaces are connected, I'd probably put it after the WORKSHOP_IMPORT_ENABLED block.

// disconnect the original video services
if ( g_pVideo )
{
    g_pVideo->Shutdown();
    g_pVideo->Disconnect();
    g_pVideo = nullptr;
}

// get video_services.dll from our game's bin folder
char video_service_path[MAX_PATH];
Q_snprintf( video_service_path, sizeof( video_service_path ), "%s\\bin\\video_services.dll", engine->GetGameDirectory() );

CSysModule *video_services_module = Sys_LoadModule( video_service_path );
if ( video_services_module != nullptr )
{
    CreateInterfaceFn VideoServicesFactory = Sys_GetFactory( video_services_module );
    if ( VideoServicesFactory )
    {
        g_pVideo = (IVideoServices *)VideoServicesFactory( VIDEO_SERVICES_INTERFACE_VERSION, NULL );
        if ( g_pVideo != nullptr )
        {
            g_pVideo->Connect( appSystemFactory );
        }
    }
}

If you needed the old video services still, I would recommend instantiating a new video services object specfically for the library, and only use it when needed.