showTextTrack in Video.js 5 - javascript

I am trying to change the active caption track from JavaScript in Video.js v5.10.4. I saw a few posts about this and they all suggested to use showTextTrack, but when I execute the command it says that showTextTrack is not a function. I currently have the following code
var video = videojs('video');
var first_track_id = video.textTracks().tracks_[0].id; // this returns vjs_track_399
video.showTextTrack(first_track_id, "captions"); // this returns the error above
Is there any other way to accomplish what I am trying to do, or what am I doing wrong?

showTextTracks() was for video.js 4. Now you just set the mode of the track to showing:
video.textTracks()[0].mode = 'showing';

Related

Javascript swiper.js Object not loading/initializing correctly (only sometimes)

I'm trying to fix the issue on a mobile website where I'm using swiper.js, but it doesn't always load correctly, which I find odd, because I have to refresh the website a couple of times and then it loads and works as expected.
Here is the whole script I'm trying to work with
let $;
const swiperSelector = '#dog-swiper-carousel .swiper-container';
let swiperRef;
let swiperId;
let slide1, slide2, slide3;
let slides;
let carousel;
window.addEventListener('load', function() {
$ = jQuery;
swiperRef = $(swiperSelector).data('swiper');
swiperRef.params.allowTouchMove = false;
swiperRef.params.noSwiping = true;
swiperRef.params.noSwipingClass = 'swiper-slide';
swiperRef.params.grabCursor = false;
swiperRef.params.navigation.nextEl = '.js-next1';
swiperRef.params.navigation.prevEl = '.js-prev1';
swiperId = document.getElementById('swiper-slide-index').children[0].children[0];
slide1 = document.getElementById('js-slide1').children[0].children[0].children[0];
slide2 = document.getElementById('js-slide2').children[0].children[0].children[0];
slide3 = document.getElementById('js-slide3').children[0].children[0].children[0];
slides = document.querySelectorAll('.mobile-card');
//Then here are a bunch of functions that take care of the navigation and perform actions on these variables
swiperRef.update();
});
I've tried to rewrite code to be more focused on vanilla js, since jQuery isn't something I'm very experienced in. I've already changed the event on window/document load from DOMContentLoaded to load, so all css styles, html elements and content can load first, before I start executing my code. However I couldn't find any issues in the code itself. I'm even creating variables and then waiting for the whole page to load before I assign values to them.
However the error I'm getting everytime I'm on the page is
Uncaught TypeError: Cannot read properties of undefined (reading 'params') at HTMLDocument.<anonymous>
And then it points to the line
swiperRef.params.allowTouchMove = false;
The problem is present only on mobile device (iPhone 12 and google chrome browser as well as safari browser). I haven't tired any other mobile devices, because I have none.

Call function without actually executing it

So I have such a weird question and I don't know if this is possible, but I will give it a shot anyways.
We have implemented OneTrust, which is a third-party cookie consent vendor and it works great and all, but we have one small hiccup that we are trying to resolve.
So within the below function:
toggleVideo: function (videoWrapper, src, cover, type, element) {
var videoElement = video.buildVideo(src, type);
// We build out video-player element
videoWrapper.html(videoElement);
// We define our variables
let onetrust = window.OneTrust;
let onetrust_obj = window.ONETRUST_MODULE;
let target = videoWrapper.html(videoElement).children('iframe');
console.log(onetrust.Close());
// Now we wait and observe for a src attribute and then show the video.
onetrust_obj.src_observer(target, function() {
video.toggle_show(videoWrapper, cover);
});
},
We have an <iframe> element that when clicked play, will wait for consent to execute - The problem is that it needs to "refresh" OneTrust so that it can change the data-src to src attribute (This is all handled using OneTrust JS, so I have no control).
When I add in the console.log(onetrust.Close());, it works just as intended and resumes playing the video when consent is given, the downfall is that it outputs an error in the console. If I remove it, the videos will not play after consent is given.
I don't want to actually execute the onetrust.Close() method as it will close the banner.
OneTrust doesn't have a proper way to "Refresh" their initialization, the techs told me that this was a one-off case, where they don't even know how to handle it.
My questions:
Is there a way that I can properly call onetrust.Close() (Seems to be the only call that actually engages the video to play after) without actually executing it?
If not, is there a way that I can somehow similarly log it, but not actually log it in the console?
Thanks all!
Strange one, may be a race-condition issue so making your code run in the next procedural iteration may resolve the issue - this can be done by adding a setTimeout with no timer value.
setTimeout(() => {
onetrust_obj.src_observer(target, function() {
video.toggle_show(videoWrapper, cover);
});
});
Alternatively, it may be worth digging into the onetrust.Close() method to see if there are any public utilities that may help 'refresh' the context you are working in.
Another idea would be to see what happens after if you ran the onetrust_obj.src_observer code block again.
EDIT: I would like to be clear that I'm just trying to help resolve debugging this, without seeing a working environment it's difficult to offer suggestions 😄

Swiper init script for mobile issue

I'm using Swiper 6.4.10 for a project. It's the first time I use Swiper.
This website has multiple sliders on 1 page. So I decided to create some initializing script. I'm using data-attributes to create the slider settings. Every slider has different setups. One of those settings is to run the slider only on a mobile device and destroy it on desktop or tablet.
I've read a whole lot of posts here and in Google but I just can't get it to work.
It is about this part:
if(container){
var initID = '#' + container;
if(mobile){
if(mobile_breakpoint.matches){
var init = new Swiper(this, settings)
} else if (!mobile_breakpoint.matches){
var init = this.swiper.destroy();
}
}
//var init = new Swiper(initID, settings)
}
When I use this code here above then all carousels are destroyed OR I get an error saying this.swiper.destroy is undefined.
When I run my code like this:
if(container){
var initID = '#' + container;
var init = new Swiper(initID, settings)
}
Then all carousels just work. When I check for data attribute mobile and try to destroy the carousels then all stop working. I clearly miss something out.
Anybody have any idea what I do wrong? Any help greatly appreciated!
"Your mistake" under else if you forgot first to Initialize swiper instance .
This is why when you uncomment this block of code - the page is broken (error: this.swiper.destroy is undefined).
To destroy an instance you first should create this instance (destroy() is a Method of swiper instance).
const swiper = new Swiper('.swiper-container', {});
swiper.destroy();
Otherwise, your code is like writing:
bla_bla.destroy(); /* Uncaught ReferenceError: bla_bla is not defined */
Create an instance (Missing in your code)
Destroy
else if (!mobile_breakpoint.matches){
var init = new Swiper(this, settings) /* missing in your code */
init = this.swiper.destroy();
}
In general - your code is very long ==> next time create a Minimal, Reproducible Example (A lot of code not related to your issue/error).

How can I access videojs.SeekBar and ControlBar in version 5?

I want to port this plugin to the new videojs version 5. I updated most of the plugin to fit into the new videojs.extend() requirements and updated the public functions declarations.
The part I'm stuck on is when you try to load the new components into videojs:
//Range Slider Time Bar
videojs.SeekBar.prototype.options_.children.RSTimeBar = {};
//Panel with the time of the range slider
videojs.ControlBar.prototype.options_.children.ControlTimePanel = {};
If I understand it correctly (I am having some doubts), it is extending specific parts of videojs in order to contain the plugin components.
The problem is that videojs.SeekBar and videojs.ControlBar are undefined and I don't know the right way to access them in v5 (or to create these empty objects if it isn't how you do it anymore). There is also no indication in the videojs wiki article "5.0 changes details"
The full code is available here.. The faulty lines are 421 and 422
EDIT
I can get rid of the error if I replace these lines with those:
videojs.getComponent("SeekBar").prototype.options_.children.RSTimeBar = {}; //Range Slider Time Bar
videojs.getComponent("ControlBar").prototype.options_.children.ControlTimePanel = {}; //Panel with the time of the range slider
but in the plugin constructor function, I can't find back the components:
//components of the plugin
var controlBar = player.controlBar;
var seekBar = controlBar.progressControl.seekBar;
this.components.RSTimeBar = seekBar.RSTimeBar; //is undefined
When I explore the videoJs object, in my debugger, I can indeed find player.controlBar.progressControl.seekBar but it has no sub-object called RSTimebar except in options_.children. It makes sense since it is where I defined it. However, I don't know why in the version 4 I can find it but not in the version 5.
EDIT 2
I notices that the RSTimebar in options_.children array was inserted as an object instead of a pair of index/string. So I changed my lines to this:
videojs.getComponent("SeekBar").prototype.options_.children.push("RSTimeBar"); //Range Slider Time Bar
videojs.getComponent("ControlBar").prototype.options_.children.push("ControlTimePanel"); //Panel with the time of the range slider
Result: the plugin is correctly loaded with one warning per component:
VIDEOJS: WARN: The RSTimeBar component was added to the videojs object
when it should be registered using videojs.registerComponent(name,
component)
I just need to figure out the proper and simplest way to correctly load the components now.
I finally managed to update the plugin thanks to a commit where most of the work was done.

Trying to access toolbar button is nil

I have been working on writing some automation scripts for an app I am writing, and have been trying to get the following function to work. I was able to finally get it to complete correctly, but with some different code. The following two code snippets are the same, in my mind, but only the FIRST one seems to work. I would love some insight as to why. Is it my JavaScript skills (which are weak, at best), or something specific to UIAutomation?
// Define some global variables -- THIS WORKS
var target = UIATarget.localTarget();
var app = target.frontMostApp().mainWindow();
var toolbarButtons = app.toolbar().buttons();
toolbarButtons["Back"].tap();
This fails...
var target = UIATarget.localTarget();
var app = target.frontMostApp().mainWindow();
var backButton = app.toolbar().buttons()["Back"];
backButton.tap();
The second (failing) code snippet says that I'm getting a nil value for the button. If someone could help point out why this second approach isn't correct, I'd greatly appreciate it. I have to tap the back button a number of times, and backButton.tap() just seems cleaner.
UPDATE: Below is the exact code that is failing
// Define some global variables
var target = UIATarget.localTarget();
var app = target.frontMostApp().mainWindow();
// List everything we see
UIALogger.logStart("Logging app...");
app.logElementTree();
UIALogger.logPass();
// Function for moving into and out of every home screen option
var homeToViewAndBack = function() {
var backButton = app.toolbar().buttons()["Back"];
// Let's go down the list of buttons
app.buttons()["VideoHomeButton"].tap();
backButton.tap();
UIALogger.logPass("Basic navigation works.");
}
// Call our functions
homeToViewAndBack();
This give an error " Script threw an uncaught JavaScript error: Cannot perform action on invalid element: UIAElementNil from target.frontMostApp().mainWindow().toolbar().buttons()["Back"]". However, the code in the first snippet above works like a charm.
To confirm again, I changed the text on the back button to "Home" and tried the following code...the first call to the back button works, but the second fails:
var homeToViewAndBack = function() {
var toolbarButtons = app.toolbar().buttons();
var backButton = app.toolbar().buttons()["Home"];
// Let's go down the list of buttons
app.buttons()[0].tap();
toolbarButtons["Home"].tap();
app.buttons()[1].tap();
backButton.tap();
UIALogger.logPass("Basic navigation works.");
}

Categories

Resources