I have a problem with embedded video. I use "Embed.ly API" and "player.js":
https://docs.embed.ly/docs/oembed
https://docs.embed.ly/docs/playerjs
I'm trying to embed a video from "youku.com" on my site. The "youku.com" is a content provider, as stated here: https://embed.ly/providers
Video is added but player's methods (play, pause and others) does not work for video. But if I changing video service from "youku.com" to "youtube.com" and use video from "youtube.com", then methods works well.
I also tried to connect the "platform.js" instead of the player. The result is the same.
Maybe the "player.js" worked before, I guess that the "youku.com" has changed its API, but the "player.js" did not track changes.
Does the player.js really work with "youku.com" now? Perhaps something should be added to my code for solve the problem? I am not in China, can it have any effect due to the fact that "youku.com" is a Chinese service?
Thanks.
My code js: (And another question: are there any errors in the code?)
var obj_json = $.getJSON('https://api.embedly.com/1/oembed?' + $.param({
url: :url, // for example: https://v.youku.com/v_show/id_XMzg2MjgwNzA0OA==.html
key: :key // my_API_key
})).done(function () {
$('.embeded').html(obj_json.responseJSON.html).find('iframe.embedly-embed').each(function () {
// initialize the player.
var player = new playerjs.Player(this);
player.on('ready', function () {
player.setLoop(true); // it is not work
player.play(); // it is not work
//..................................
// There are also special buttons on the page, clicking on which the video should start or stop:
$('.button_play').click(function () {
player.play(); // pressing occurs, but player it is not work
});
$('.button_pause').click(function () {
player.pause(); // pressing occurs, but player it is not work
});
//.........................................
});
});
});
Related
Here I found an example how I can listen Play\Pause button of youtube iframe.
player.addEventListener('onStateChange', function(e) {
console.log('State is:', e.data);
});
Now I need to listen the volume changes.
In the youtube documentation and here I found a method player.getVolume(), but I have no idea how this method can be implemented if I want to be informed about volume changes from iframe side, instead of ask iframe from my side.
On YouTube Player Demo page such functionality exists (when I change the volume of a player, I see appropriate changes in the row Volume, (0-100) [current level: **]), but neither in the doc nor in internet I can not find how to implement it.
I also tried to use the above mentioned code with onApiChange event (it is not clear for me what this event actually does), like:
player.addEventListener('onApiChange', function(e) {
console.log('onApiChange is:', e.data);
});
but console shows nothing new.
player.getOptions(); shows Promise {<resolved>: Array(0)}.
Could anyone show an example?
See this question.
You can listen to postMessage events emitted by the IFrame and react only to the volume change ones:
// Instantiate the Player.
function onYouTubeIframeAPIReady() {
var player = new YT.Player("player", {
height: "390",
width: "640",
videoId: "dQw4w9WgXcQ"
});
// This is the source "window" that will emit the events.
var iframeWindow = player.getIframe().contentWindow;
// Listen to events triggered by postMessage.
window.addEventListener("message", function(event) {
// Check that the event was sent from the YouTube IFrame.
if (event.source === iframeWindow) {
var data = JSON.parse(event.data);
// The "infoDelivery" event is used by YT to transmit any
// kind of information change in the player,
// such as the current time or a volume change.
if (
data.event === "infoDelivery" &&
data.info &&
data.info.volume
) {
console.log(data.info.volume); // there's also data.info.muted (a boolean)
}
}
});
}
See it live.
Note that this relies on a private API that may change at anytime without previous notice.
I inspected the code of YouTube Player Demo page and found that the html line which shows the current YouTube volume (<span id="volume">**</span>) constantly blinking (~ 2 times per 1 sec), so I can assume this demo page uses something like this:
// YouTube returns Promise, but we need actual data
self = this
setInterval(function () { self.player.getVolume().then(data => { self.volumeLv = data }) }, 250)
Possibly not the best method, but it seems there is no other option (I also tried to listen changes in the appropriate style of the volume bar, but no luck due to the cross-origin problem).
So, this let us 'listen' volume changes of youtube.
Just in case, if someone wants to set youtube volume, you need to use [this.]player.setVolume(volume_from_0_to_100)
I have a web application integrating with the SoundCloud API for searching and playing tracks. I can successfully stream tracks through the API using SoundCloud oEmbed like so:
scope.playTrack = function(track) {
SC.oEmbed(track.permalink_url, { auto_play: true })
.then(function(oEmbed) {
scope.soundCloudWidget = $sce.trustAsHtml(oEmbed.html);
scope.$apply();
});
};
With the widget bound to the view:
<div ng-bind-html="soundCloudWidget"></div >
This is working as expected. My issue is I would like to stream a track in this way but with a specified start and stop time. I did some research and found a seemingly related StackOverflow question/answer that mentions one can:
append #t=12s to the sound's URL to start it at 12th second
This works when constructing a URL like:
https://soundcloud.com/griz/summer-97-ft-muzzy-bearr#t=54s
However, for start = '54s' I would like to do something like this
scope.playTrackSection = function(track, start) {
SC.oEmbed(track.permalink_url, { auto_play: true, t: start })
.then(function(oEmbed) {
scope.soundCloudWidget = $sce.trustAsHtml(oEmbed.html);
scope.$apply();
});
};
or
scope.playTrackSection = function(track, start) {
var url = track.permalink_url + "#t=" + start;
SC.oEmbed(track.permalink_url, { auto_play: true })
.then(function(oEmbed) {
scope.soundCloudWidget = $sce.trustAsHtml(oEmbed.html);
scope.$apply();
});
};
But to no avail. Is there any possible way to specify a start time in this type of context?
Bonus points: Additionally is there any possible way to specify a duration or time when a streaming song should stop playing?
Figured it out. SoundCloud Widget API to the rescue!
In order to access the JavaScript object which provides the SoundCloud Widget API, add this script to your html page.
This script exposes the SC.Widget(/*iframeElement|iframeElementID*/) function to the global scope. It allows you to control the widget from the parent page (the page the widget is inserted into). SC.Widget accepts the reference to the iframe element or its id.
So after adding this script I was able to do something like this:
scope.playTrackSection = function(track, startTime, endTime) {
SC.oEmbed(track.permalink_url, { auto_play: true })
.then(function(oEmbed) {
scope.soundCloudWidget = $sce.trustAsHtml(oEmbed.html);
scope.$apply();
scope.iframe = document.getElementById('soundcloud_widget').querySelector('iframe');
scope.widget = SC.Widget(scope.iframe);
scope.widget.seekTo(startTime);
scope.widget.bind('playProgress', function(needle) {
if (needle.currentPosition >= endTime) {
scope.widget.pause();
}
});
});
};
With html:
<div id="soundcloud_widget" ng-bind-html="soundCloudWidget"></div>
It is also useful to know that scope.widget.bind('xxxx', ....) can be used to bind into several Event types of the Widget API. So if you want certain things to happen when a user pauses, plays, finishes, seeks, etc. you can hook into these events.
I am using 'angualr-youtube-embed' directive to embed youtube player in my angular web app. In that I have to identify play and pause and volume change events. To listen play and pause events I am using the below given code.
$scope.$on('youtube.player.playing', function ($event, player) {
// to do functions when the video is playing.
});
$scope.$on('youtube.player.paused', function ($event, player) {
// to do functions when the video is paused.
});
Now my requirement is, I want to do some works while changing volume in youtube player, I need to identify that volume change event. But I have no idea about how to listen the volume change in youtube player. How can I solve this issue?
Thanks in advance.
Just in case if anyone has the same question, here is my full answer.
For today the code looks like:
setInterval(this.getChangedVolume, 250)
getChangedVolume () {
let currentYoutubeVolume = this.player.getVolume()
// Do some things, for example (will show Promise):
// console.log(currentYoutubeVolume)
// YouTube returns Promise, but we need actual data, so:
// Promise.resolve(currentYoutubeVolume).then(data => { this.volumeLv = data })
}
player.getVolume():Number
Returns the player's current volume, an integer between 0 and 100. Note that getVolume() will return the volume even if the player is muted.
For more Detail check this: YouTube Player Controls
i'm using video-js media player with flash fallback to dynamically play and change mp4-videos (h.264 - only source available) on a site i'm working on.
My problem is, every time i'm changing the video/source, the browser eats more and more memory until it is out of memory and crashes.
the problem occurs on every browser, flash player hardware acceleration enabled and disabled.
Player is initialized like this:
_V_.options.flash.swf = "../Scripts/ThirdParty/video-js.swf";
_V_.options.flash.iFrameMode = true; //false didn't help
_V_.players = {};
_V_("main_video", { "techOrder": ["flash", "html5"] }).ready(function () {
$.b4dvideo.videoPlayer = this;
if (!$.b4dvideo.contentInitialised) {
$.b4dvideo.contentInitialised = true;
$.b4dvideo._loadContent();
}
this.on("pause", function () {
this.posterImage.show()
});
this.on("ended", function () {
$.b4dvideo.videoPlayer.pause();
$.b4dvideo.videoPlayer.currentTime(0);
$.b4dvideo.videoPlayer.pause();
this.posterImage.show()
});
});
And changing the source of the player
if (!$.b4dvideo.videoPlayer.paused()) {
$.b4dvideo.videoPlayer.pause();
}
$.b4dvideo.videoPlayer.currentTime(0);
$.b4dvideo.videoPlayer.pause();
$.b4dvideo.videoPlayer.src(videoPath);
$.b4dvideo.videoPlayer.play();
It looks like the flash player is keeping the whole video in memory and never releasing it.
Any ideas on that?
I have even tried using jwplayer - same problem :-(
Update 1:
I also created a js-fiddle demonstrating this issue... just press play several times and watch your memory
http://jsfiddle.net/fwcJh/2/
On VideoJS website you state that support was moved to StackOverflow, so let's try it here. I've got the following code:
var player = _V_('the_id', {}, function(){
jQuery('.remove').on('click.destroyvideojs', function(){
player.destroy();
jQuery(this).unbind('click.destroyvideojs');
});
});
It initializes video at first and it destroys it.
But when I want to initialize it again using the same exact piece of code, it doesn't work. It doesn't initialize the script on the same element ID (when it was removed from DOM and added again with correct initialization call after it's been added). I'm wondering why this might be happening?
Another try today:
var the_id = 'my_id';
var player = _V_(the_id, {}, function(){
player.destroy();
_V_(the_id, {}, function(){
alert('reinit');
});
});
So, re-initialization of VideoJS simply doesn't work. Furthermore, it removed controls from the video now.
In case this helps anyone, it looks like it's dispose in Version 4:
var player = videojs('my-video');
player.dispose();
Having looked at the source for Video.js 5.0.0. #l:17236 You can just do the following:
if(videojs.getPlayers()[id]) {
delete videojs.getPlayers()[id];
}
It seems that player hasn't been defined when the callback executes.
Take a look at this js fiddle http://jsfiddle.net/gaboesquivel/BA8Pm/
destroy(); works for me. this how the function looks like
destroy: function () {
this.stopTrackingProgress();
this.stopTrackingCurrentTime();
_V_.players[this.id] = null;
delete _V_.players[this.id];
this.tech.destroy();
this.el.parentNode.removeChild(this.el)
}
check this solution too
http://help.videojs.com/discussions/problems/861-how-to-destroy-a-video-js-object#comment_13544514
I pulled some of My hare from My head, very hard to find response fore such questions...
So here is My solution, with JQuery... the solution was born from the question how to destroy uninitialised player objects, you guys save my day in the end, cos We can destroy only players that are shown, and even if I clean the HTML and reinitialise dynamically playerJs the flash fall back will not work for unshowed undestroyed media-player.
so here is the solution:
$.each(_V_.players, function (key, player) {
if (player.isReady) { player.destroy(); }
else { delete _V_.players[player.id]; }
});
a little messy but will do just fine.
cheers!
The api reference your looking for is .dispose(); however it does not remove settings from the dom. If you have third party plugins other items may litter your DOM after the dispose is run. To run dispose and clean up your dom use a code like this
dispose = function() {
if (settings.debug) {
console.info('place.videojs_element.dispose()');
} /*Target the Player Element*/
var player = videojs(settings.element.id + '_player'); /*Pause Video*/
player.pause(); /*Wait for third party scripts to stop listening!!! <-- Important*/
setTimeout(function() { /*Dispose of the player*/
player.dispose();
/*I have a new video element waiting to be placed ( this code is proprietary )*/
var epi = new EPI();
epi.place.videojs_element(settings, data); /*Wait time 600ms*/
}, 600); /*Destroy the old video element <--- Important */
$('#' + settings.element.id).empty();
}
See a working example in action: http://codepen.io/JaminQuimby/pen/yNaOwz/
The above will give you a clean DOM and completely remove the video player.