From f6e3d09ed68633d017353395e41914c49981bc82 Mon Sep 17 00:00:00 2001 From: ed-thuando Date: Tue, 14 Apr 2026 13:21:03 +0700 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20resolve=20#1122=20=E2=80=94=20Samsun?= =?UTF-8?q?g=20smart=20TV=20support=20(browser)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #1122 Signed-off-by: ed-thuando <231172918+ed-thuando@users.noreply.github.com> --- .../javascripts/streama/streama.services.js | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 grails-app/assets/javascripts/streama/streama.services.js diff --git a/grails-app/assets/javascripts/streama/streama.services.js b/grails-app/assets/javascripts/streama/streama.services.js new file mode 100644 index 00000000..1f216a23 --- /dev/null +++ b/grails-app/assets/javascripts/streama/streama.services.js @@ -0,0 +1,118 @@ +//= wrapped + +angular.module('streama').factory('$streamaPlayerCleanup', [ + '$window', '$timeout', + function($window, $timeout) { + + var cleanupConfig = { + verbose: false, + timeout: 100 + }; + + + function log() { + if (cleanupConfig.verbose && console) { + console.log.apply(console, ['[streama-player-cleanup]'].concat(Array.prototype.slice.call(arguments))); + } + } + + function removeEventListeners(element) { + if (!element) return; + + var clone = element.cloneNode(false); + clone.removeAttribute('id'); + clone.removeAttribute('src'); + clone.load && clone.load(); + + while (element.parentNode && element.parentNode.children.length > 0) { + try { + element.parentNode.replaceChild(clone, element.parentNode.lastChild); + } catch (e) { + break; + } + } + } + + function clearMediaSource(element) { + if (!element || !element.src) return; + + try { + var oldSrc = element.src; + element.removeAttribute('src'); + element.load && element.load(); + + if ($window.URL && $window.URL.createObjectURL) { + if (oldSrc && oldSrc.startsWith('blob:')) { + $window.URL.revokeObjectURL(oldSrc); + } + } + } catch (e) { + log('Error clearing media source:', e); + } + } + + function pauseAndReset(element) { + if (!element) return; + + try { + element.pause(); + element.currentTime = 0; + element.removeAttribute('src'); + element.load && element.load(); + element.poster = ''; + } catch (e) { + log('Error pausing and resetting element:', e); + } + } + + function removeVideoElements(container) { + if (!container) return; + + var videos = container.querySelectorAll ? container.querySelectorAll('video') : []; + + angular.forEach(videos, function(video) { + pauseAndReset(video); + clearMediaSource(video); + removeEventListeners(video); + }); + + log('Removed', videos.length, 'video element(s)'); + } + + function clearSourceBufferExtension() { + if (!HTMLMediaElement || !HTMLMediaElement.prototype) return; + + + try { + delete HTMLMediaElement.prototype.disconnect; + delete HTMLMediaElement.prototype.connectMediaSource; + } catch (e) { + log('Could not clear source buffer extension:', e); + } + } + + function forceCleanup(container) { + log('Starting force cleanup'); + + removeVideoElements(container || document.body); + + clearSourceBufferExtension(); + + $timeout(function() { + log('Force cleanup completed'); + }, cleanupConfig.timeout); + } + + function setVerbose(mode) { + cleanupConfig.verbose = !!mode; + } + + return { + forceCleanup: forceCleanup, + setVerbose: setVerbose, + pauseAndReset: pauseAndReset, + clearMediaSource: clearMediaSource, + removeEventListeners: removeEventListeners + }; + } +]); From e43ed1d0821bddf8133c52f6156502cc16f66124 Mon Sep 17 00:00:00 2001 From: ed-thuando Date: Tue, 14 Apr 2026 13:21:04 +0700 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20resolve=20#1122=20=E2=80=94=20Samsun?= =?UTF-8?q?g=20smart=20TV=20support=20(browser)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #1122 Signed-off-by: ed-thuando <231172918+ed-thuando@users.noreply.github.com> --- grails-app/assets/javascripts/streama/controllers/player-ctrl.js | 1 + 1 file changed, 1 insertion(+) diff --git a/grails-app/assets/javascripts/streama/controllers/player-ctrl.js b/grails-app/assets/javascripts/streama/controllers/player-ctrl.js index 21dfbe11..0ac87655 100644 --- a/grails-app/assets/javascripts/streama/controllers/player-ctrl.js +++ b/grails-app/assets/javascripts/streama/controllers/player-ctrl.js @@ -10,6 +10,7 @@ angular.module('streama').controller('playerCtrl', [ var missingFileError = playerService.handleMissingFileError($scope.video); if(!missingFileError){ + playerService.destroyPlayer(); $scope.videoOptions = playerService.setVideoOptions($scope.video, $rootScope.settings); } From c167ccb2c59b7671cebaf29af5c6019ddd148a3d Mon Sep 17 00:00:00 2001 From: ed-thuando Date: Tue, 14 Apr 2026 13:21:05 +0700 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20resolve=20#1122=20=E2=80=94=20Samsun?= =?UTF-8?q?g=20smart=20TV=20support=20(browser)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #1122 Signed-off-by: ed-thuando <231172918+ed-thuando@users.noreply.github.com> --- grails-app/conf/ApplicationResources.groovy | 63 +++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 grails-app/conf/ApplicationResources.groovy diff --git a/grails-app/conf/ApplicationResources.groovy b/grails-app/conf/ApplicationResources.groovy new file mode 100644 index 00000000..abdd43b6 --- /dev/null +++ b/grails-app/conf/ApplicationResources.groovy @@ -0,0 +1,63 @@ +modules = { + core { + dependsOn 'jquery, common' + resource url: '/css/main.css' + resource url: '/css/errors.css' + resource url: '/css/main-classes.css' + resource url: '/js/jquery-2.2.0.min.js' + resource url: '/js/bootstrap.min.js' + resource url: '/js/bootstrap-datetimepicker.js' + resource url: '/js/common.js' + } + + auth { + dependsOn 'jquery, common' + resource url: '/css/bootstrap-social.css' + resource url: '/css/bootstrap-social.css' + } + + videojs { + dependsOn 'jquery' + resource url: '/js/video.js' + } + + angular { + dependsOn 'jquery' + resource url: '/js/angular.min.js' + resource url: '/js/angular-animate.min.js' + resource url: '/js/angular-route.min.js' + resource url: '/js/angular-cookies.min.js' + resource url: '/js/angular-resource.min.js' + resource url: '/js/angular-translate.min.js' + resource url: '/js/ng-file-upload-shim.min.js' + resource url: '/js/ng-file-upload.min.js' + resource url: '/js/ui-bootstrap-tpls.min.js' + resource url: '/js/pagination.js' + resource url: '/js/dirPagination.js' + resource url: '/js/messages_en.js' + resource url: '/js/messages_de.js' + resource url: '/js/messages_es.js' + resource url: '/js/messages_pt.js' + resource url: '/js/messages_fr.js' + resource url: '/js/messages_nl.js' + resource url: '/js/messages_it.js' + resource url: '/js/angular-ui.min.js' + } + + app { + dependsOn 'jquery, common, videojs, angular' + resource url: '/css/player.css' + resource url: '/css/video-js.css' + resource url: '/js/app.js' + resource url: '/js/services/playerServices.js' + resource url: '/js/services/authServices.js' + resource url: '/js/services/showServices.js' + resource url: '/js/services/resourceServices.js' + resource url: '/js/services/settingsServices.js' + resource url: '/js/services/videoServices.js' + resource url: '/js/services/partyServices.js' + resource url: '/js/services/adminServices.js' + resource url: '/js/directives/streamaDirective.js' + resource url: '/js/directives/playerDirective.js' + } +} \ No newline at end of file