Skip to content

Commit

Permalink
Merge pull request #89 from alexmercerind/improvements
Browse files Browse the repository at this point in the history
Fixed memory leaks & improved cleanup.
  • Loading branch information
alexmercerind authored Aug 5, 2021
2 parents 44b4a32 + 9244262 commit 8c4abdc
Show file tree
Hide file tree
Showing 38 changed files with 289 additions and 215 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ jobs:
- run: flutter config --enable-windows-desktop
- run: flutter pub get
- run: flutter build windows --verbose
- uses: actions/upload-artifact@v1
with:
name: dart_vlc_example
path: example/build/windows/runner/Release

build_linux:
name: Build Linux
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.1.1

- Fixed setState being called after dispose (#75) (Finally)
- Improved memory management.
- Fixed ton of memory leaks.
- Fixed `Devices::all` & `Media::parse` causing crash on Windows.

## 0.1.0

- Fixed build on Linux.
Expand Down
18 changes: 6 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<h4 align="center">Flutter 🎞 media playback, broadcast, recording & chromecast library for Windows & Linux.</h4>
<h5 align="center">Written in C++ using libVLC & libVLC++.</h5>

![](https://github.com/alexmercerind/dart_vlc/blob/assets/dart_vlc_6.png?raw=true)
![](https://github.com/alexmercerind/dart_vlc/blob/assets/dart_vlc_windows_11_1.PNG?raw=true)

![](https://github.com/alexmercerind/dart_vlc/blob/assets/dart_vlc_7.png?raw=true)
![](https://github.com/alexmercerind/dart_vlc/blob/assets/dart_vlc_windows_11_2.PNG?raw=true)

## Installation

Expand All @@ -13,33 +13,27 @@
```yaml
dependencies:
...
dart_vlc: ^0.0.9
dart_vlc: ^0.1.1
```
**Dart CLI**
```yaml
dependencies:
...
dart_vlc_ffi: ^0.0.1
dart_vlc_ffi: ^0.1.0
```
More on Dart CLI implementation [here](./ffi/README.md).
Feel free to open issue, incase you find something to be not working.
## Support
Consider supporting the project by starring the repository or buying me a coffee.
<a href="https://www.buymeacoffee.com/alexmercerind"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=alexmercerind&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff"></a>
**Donate in Crypto**
- ETH (Ethereum)
- `0x92f92BC204cDFDAB655e6A69e5Aa4bA5476D7661`
- BTC (Bitcoin)
- `1M3DNwnX1GDauPoPr7VywojMRWygje8ctq`

Thanks a lot for your support.
Looking for contributors for macOS port.
Expand Down Expand Up @@ -328,7 +322,7 @@ You can see an example project [here](https://github.com/alexmercerind/dart_vlc/

Windows

![](https://github.com/alexmercerind/dart_vlc/blob/assets/dart_vlc_0.PNG?raw=true)
![](https://github.com/alexmercerind/dart_vlc/blob/assets/dart_vlc_6.png?raw=true)


## Workings
Expand Down
8 changes: 7 additions & 1 deletion dartvlc/broadcast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ class Broadcast {
);
}

void dispose() {
~Broadcast() {
libvlc_vlm_release(this->instance.get());
delete this->media;
}

private:
Expand All @@ -89,6 +90,11 @@ class Broadcasts {
return this->broadcasts[id];
}

void dispose(int id, std::function<void()> callback = []() -> void {}) {
delete this->broadcasts[id];
callback();
}

private:
std::map<int, Broadcast*> broadcasts;
};
Expand Down
8 changes: 7 additions & 1 deletion dartvlc/chromecast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ class Chromecast {
);
}

void dispose() {
~Chromecast() {
libvlc_vlm_release(this->instance.get());
delete this->media;
}

private:
Expand All @@ -66,6 +67,11 @@ class Chromecasts {
return this->chromecasts[id];
}

void dispose(int id, std::function<void()> callback = []() -> void {}) {
delete this->chromecasts[id];
callback();
}

private:
std::map<int, Chromecast*> chromecasts;
};
Expand Down
3 changes: 3 additions & 0 deletions dartvlc/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class Devices {
std::vector<Device*> all;

void refresh() {
for (Device* device: this->all) {
delete device;
}
this->all.clear();
VLC::Instance _ = VLC::Instance(0, nullptr);
VLC::MediaPlayer __ = VLC::MediaPlayer(_);
Expand Down
5 changes: 5 additions & 0 deletions dartvlc/equalizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ class Equalizers {
return id;
}

void dispose(int id, std::function<void()> callback = []() -> void {}) {
delete this->equalizers[id];
callback();
}

private:
std::map<int, Equalizer*> equalizers;
};
Expand Down
2 changes: 1 addition & 1 deletion dartvlc/internal/events.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class PlayerEvents : public PlayerGetters {
if (this->isPlaylistModified) {
this->mediaListPlayer.setMediaList(this->mediaList);
if (!this->mediaList.count()) {
this->state = new PlayerState();
this->state->reset();
this->mediaListPlayer.stop();
return;
}
Expand Down
29 changes: 17 additions & 12 deletions dartvlc/internal/setters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,34 @@
class PlayerSetters: public PlayerEvents {
public:
void open(MediaSource* mediaSource, bool autoStart = true) {
if (this->state->device == nullptr)
this->stop();
this->state->medias = new Playlist({}, PlaylistMode::single);
/* Freed the previous `Media` objects when a new `Playlist` or `Media` is opened. */
for (Media* media: this->state->medias->medias) {
delete media;
}
this->stop();
this->state->medias->medias = {};
this->mediaList = VLC::MediaList(this->instance);
if (mediaSource->mediaSourceType() == "MediaSourceType.media") {
Media* media = dynamic_cast<Media*>(mediaSource);
VLC::Media _ = VLC::Media(this->instance, media->location, VLC::Media::FromLocation);
this->mediaList.addMedia(_);
this->mediaListPlayer.setMediaList(this->mediaList);
this->state->medias = new Playlist({ media }, PlaylistMode::single);
this->state->medias->medias = { media };
this->state->isPlaylist = false;

}
else if (mediaSource->mediaSourceType() == "MediaSourceType.playlist") {
Playlist* playlist = dynamic_cast<Playlist*>(mediaSource);
if (playlist->medias.empty())
return;
for (Media* _ : playlist->medias) {
VLC::Media media = VLC::Media(this->instance, _->location, VLC::Media::FromLocation);
this->mediaList.addMedia(media);
for (Media* media : playlist->medias) {
VLC::Media _ = VLC::Media(this->instance, media->location, VLC::Media::FromLocation);
this->mediaList.addMedia(_);
}
this->mediaListPlayer.setMediaList(this->mediaList);
this->state->medias = playlist;
this->state->medias->medias = playlist->medias;
this->state->isPlaylist = true;
}
this->_onOpenCallback(this->mediaList.itemAtIndex(0));

this->mediaListPlayer.playItemAtIndex(0);
this->state->index = 0;
this->state->isPlaying = this->mediaListPlayer.isPlaying();
Expand Down Expand Up @@ -123,7 +124,6 @@ class PlayerSetters: public PlayerEvents {

void setEqualizer(Equalizer* equalizer) {
this->mediaPlayer.setEqualizer(equalizer->equalizer);
this->state->equalizer = equalizer;
}

void setUserAgent(std::string userAgent) {
Expand Down Expand Up @@ -173,7 +173,12 @@ class PlayerSetters: public PlayerEvents {
}

void move(int initial, int final) {
if (initial < 0 || initial >= this->state->medias->medias.size() || final < 0 || final >= this->state->medias->medias.size()) return;
if (
initial < 0 ||
initial >= this->state->medias->medias.size() ||
final < 0 ||
final >= this->state->medias->medias.size()
) return;
if (initial == final) return;
this->isPlaylistModified = true;
Media* _ = this->state->medias->medias[initial];
Expand Down
24 changes: 24 additions & 0 deletions dartvlc/internal/state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,29 @@ class PlayerState {
float rate = 1.0;
bool isPlaylist = false;
Device* device = nullptr;
/* TODO: Not used yet.
Equalizer* equalizer = nullptr;
*/

void reset() {
this->index = 0;
this->medias->medias = {};
this->isPlaying = false;
this->isValid = true;
this->isSeekable = true;
this->isCompleted = false;
this->position = 0;
this->duration = 0;
this->volume = 1.0;
this->rate = 1.0;
this->isPlaylist = false;
this->device = nullptr;
/*
this->equalizer = nullptr;
*/
}

~PlayerState() {
delete this->medias;
}
};
29 changes: 12 additions & 17 deletions dartvlc/mediasource/media.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
VLC::Instance instance = VLC::Instance(0, nullptr);


/* Media object is cleared inside PlayerSetters::open. */
class Media: public MediaSource {
public:
int id;
Expand Down Expand Up @@ -51,24 +52,26 @@ class Media: public MediaSource {
return media;
}

static Media* asset(int id, std::string path, bool parse = false, int timeout = 10000) {
static Media* directShow(int id, std::string resource) {
Media* media = new Media();
media->id = id;
media->resource = path;
media->location = "file:///" + std::filesystem::temp_directory_path().u8string() + "/" + path;
media->mediaType = "MediaType.asset";
if (parse) media->parse(timeout);
media->resource = resource;
media->location = resource;
media->mediaType = "MediaType.directShow";
return media;
}

static Media* directShow(int id, std::string resource) {
/* Now done directly from dart_vlc.
static Media* asset(int id, std::string path, bool parse = false, int timeout = 10000) {
Media* media = new Media();
media->id = id;
media->resource = resource;
media->location = resource;
media->mediaType = "MediaType.directShow";
media->resource = path;
media->location = "file:///" + std::filesystem::temp_directory_path().u8string() + "/" + path;
media->mediaType = "MediaType.asset";
if (parse) media->parse(timeout);
return media;
}
*/

void parse(int timeout) {
VLC::Media media = VLC::Media(instance, this->location, VLC::Media::FromLocation);
Expand Down Expand Up @@ -113,14 +116,6 @@ class Media: public MediaSource {
std::string mediaSourceType() {
return "MediaSourceType.media";
}

std::map<std::string, std::string> get() {
std::map<std::string, std::string> media;
media["id"] = this->id;
media["mediaType"] = this->mediaType;
media["resource"] = this->resource;
return media;
}
};


Expand Down
10 changes: 1 addition & 9 deletions dartvlc/mediasource/playlist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,7 @@ class Playlist : public MediaSource {
this->medias = medias;
this->playlistMode = playlistMode;
};

std::vector<std::map<std::string, std::string>> get() {
std::vector<std::map<std::string, std::string>> _medias;
for (Media* audio : this->medias) {
_medias.emplace_back(audio->get());
}
return _medias;
}


std::string mediaSourceType() {
return "MediaSourceType.playlist";
}
Expand Down
24 changes: 21 additions & 3 deletions dartvlc/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ class Player: public PlayerSetters {
this->instance = VLC::Instance(0, nullptr);
}
else {
char** args = new char*[commandlineArguments.size()];
for (int index = 0; index < commandlineArguments.size(); index++) args[index] = commandlineArguments[index].data();
this->instance = VLC::Instance(static_cast<int>(commandlineArguments.size()), args);
this->argsSize = commandlineArguments.size();
this->args = new char*[commandlineArguments.size()];
for (int index = 0; index < commandlineArguments.size(); index++) this->args[index] = commandlineArguments[index].data();
this->instance = VLC::Instance(static_cast<int>(commandlineArguments.size()), this->args);
}
this->mediaPlayer = VLC::MediaPlayer(this->instance);
this->mediaListPlayer = VLC::MediaListPlayer(this->instance);
Expand Down Expand Up @@ -54,6 +55,18 @@ class Player: public PlayerSetters {
void onException(std::function<void(void)> callback) {
this->mediaPlayer.eventManager().onEncounteredError(callback);
}

~Player() {
this->mediaPlayer.stop();
delete this->state;
delete this->_videoFrameBuffer;
for (size_t i = 0; i < argsSize; i++) delete this->args[i];
delete[] this->args;
}

private:
char** args;
size_t argsSize;
};


Expand All @@ -66,6 +79,11 @@ class Players {
return this->players[id];
}

void dispose(int id, std::function<void()> callback = []() -> void {}) {
delete this->players[id];
callback();
}

private:
std::map<int, Player*> players;
};
Expand Down
8 changes: 7 additions & 1 deletion dartvlc/record.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ class Record {
);
}

void dispose() {
~Record() {
libvlc_vlm_release(this->instance.get());
delete this->media;
}

private:
Expand All @@ -66,6 +67,11 @@ class Records {
return this->records[id];
}

void dispose(int id, std::function<void()> callback = []() -> void {}) {
delete this->records[id];
callback();
}

private:
std::map<int, Record*> records;
};
Expand Down
Loading

0 comments on commit 8c4abdc

Please sign in to comment.