[Archived] A cross-platform simple media playback library for C/C++.
The project is now archived. Reasons are documented below:
GStreamer
, so I decided to summon a WebKit
instance using webview.h to make a basic JS interop setup for using WebAudio API (which itself is based on GStreamer in WebKitGTK). A good advantage that Flutter provides over other electron.js like alternatives is that it doesn't start a webview instance / JavaScript runtime, but using this plugin puts Flutter's those advantages to no use. This also makes us unable to add various crucial features like audio device selection/enumeration or equalizer etc. in future because of limited set of WebAudio APIs.std::stof
and std::stoi
when doing JS interop. It is both inefficient and unsafe.The project was started as an internal Harmonoid dependency to provide Windows/Linux support for the time-being, while I was looking for other libraries to settle on. Now that it is no longer used & current implementation isn't good enough, I don't see any point in adding features, fixing bugs etc. Thus, I have decided to discontinue this project. You are free to fork the project or use the code as allowed by the MIT license (which can be found in the LICENSE file).
Thankyou.
A very simple example can be as follows.
#include "libwinmedia/libwinmedia.hpp"
int32_t main(int32_t ac, const char** av) {
using namespace std;
using namespace lwm;
if (ac < 2) {
cout << "No URI provided.\n"
<< "Example Usage:\n" << av[0]
<< " file://C:/alexmercerind/music.mp3\n" << av[0]
<< " https://alexmercerind.github.io/video.mp4\n";
return EXIT_FAILURE;
}
auto player = Player(0);
auto media = Media(av[1]);
player.Open(vector<Media>{media});
player.Play();
player.events()->Position([](int32_t position) -> void {
cout << "Current playback position is " << position << " ms.\n";
});
cin.get();
return EXIT_SUCCESS;
}
More about Flutter here or on the pub.dev.
dependencies:
...
libwinmedia: ^0.0.1
import 'package:libwinmedia/libwinmedia.dart';
void main() {
LWM.initialize();
runApp(MyApp());
}
void demo() {
var player = Player(id: 0);
player.streams.medias.listen((List<Media> medias) {});
player.streams.isPlaying.listen((bool isPlaying) {});
player.streams.isBuffering.listen((bool isBuffering) {});
player.streams.isCompleted.listen((bool isCompleted) {});
player.streams.position.listen((Duration position) {});
player.streams.duration.listen((Duration duration) {});
player.streams.index.listen((int index) {});
player.open([
Media(uri: 'https://www.example.com/media/music.mp3'),
Media(uri: 'file://C:/documents/video.mp4'),
]);
player.play();
player.seek(Duration(seconds: 20));
player.nativeControls.update(
album: 'Fine Line',
albumArtist: 'Harry Styles',
trackCount: 12,
artist: 'Harry Styles',
title: 'Lights Up',
trackNumber: 1,
thumbnail: File('album_art.png'),
);
}
Consider supporting the project by starring the repository or buying me a coffee.
Thanks a lot for your support.
For using the library on Windows, you can download the pre-compiled shared library from the releases page & headers can be found here.
Create a new player.
Player player = Player(0);
Create a media to open inside player.
Media media = Media("file://C:/alexmercerind/music.mp3");
int32_t duration = media.duration();
Play the medias.
player.Open(std::vector<lwm::Media>{media});
Control playback.
player.Play();
player.Pause();
player.SetVolume(0.69);
player.SetRate(1.2);
player.Seek(10000);
player.SetIsLooping(false);
player.SetAudioBalance(1.0);
Listen to playback events.
player.events()->Position(
[=](int position) -> void {}
);
player.events()->Duration(
[=](int duration) -> void {}
);
player.events()->Rate(
[=](float rate) -> void {}
);
player.events()->Volume(
[=](float volume) -> void {}
);
player.events()->IsPlaying(
[=](bool isPlaying) -> void {}
);
// Other events.
Create native system media controls.
Pass function as argument to receive event callbacks.
auto controls = lwm::NativeControls(
[](auto button) -> void {
if (button == NativeControlsButton::Play) std::cout << "Play clicked.\n";
if (button == NativeControlsButton::Pause) std::cout << "Pause clicked.\n";
}
);
Update the native system media controls.
controls.Update(
std::make_shared<lwm::MusicNativeControlState>(
"album_artist",
"album",
"track_count",
"artist",
"title",
"track_number"
),
"file://C:/Users/Hitesh/Pictures/AlbumArt.PNG"
);
Clear the native system media controls.
controls.Dispose();
Extract metadata tags.
auto tags = lwm::Tags::FromMusic(std::wstring(music_file));
std::wcout << "album : " << tags.album() << ".\n"
<< "album_artist : " << tags.album_artist() << ".\n"
<< "bitrate : " << tags.bitrate() << ".\n";
// Other metadata tags.
Extract album art.
lwm::Tags::ExtractThumbnail(
music_file,
TO_WIDESTRING(std::filesystem::current_path().string()),
"ExtractedAlbumArt.PNG",
lwm::ThumbnailMode::Music,
400
);
Show video in a window.
For showing video, you must instantiate player as follows.
Player player = Player(0, true);
Control video output.
player.ShowWindow();
player.CloseWindow();
For showing video
You need to embed a manifest with maxversiontested
property to the generated executable. The library creates a separate win32 window on another thread & uses XAML islands to render the MediaPlayerElement
in it (for showing video). Learn more here & here.
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<maxversiontested Id="10.0.18362.0"/>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
</assembly>
The main goals of creating libwinmedia are:
** Currently only working on Windows & Linux.
Copyright (c) 2021 Hitesh Kumar Saini [email protected]
This library & work under this repository is MIT licensed.
Contributions welcomed.