I was tasked to capture the image on a specific time when visiting youtube. So far I haven't got any success using chromium. For example, i need to capture the image of a video exactly after 180 seconds, i will have to visit this URL https://www.youtube.com/watch?v=Biagyb7AcK8&t=180s , what i did is to issue pause command OnChromiumLoadEnd but it fails depending on internet speed.. Are there any command to make video is paused on a specific time?
EDIT
here is my code OnChromiumLoadEnd:
begin
CEFWindowParent1.SetFocus;
Sleep(200);
keybd_event(Ord('K'), 0, 0, 0);
end;
Related
I want to get the total duration of a current live stream on YouTube (not ended!). This is straightforward for normal videos, e.g.:
https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id={VIDEO_ID}&key={KEY}
However, for live streams such as Earth live from ISS this just returns a duration of "PT0S" which essentially means it's 0 seconds long.
There should be a way to get it. One way to get it is via Javascript, if you have the live stream open in your browser:
ytplayer = document.getElementById("movie_player");
console.log("Duration: " + ytplayer.getDuration());
Is it possible to get from a server-side? Other people have asked the same but have not received an answer yet.
Edit: I've just noticed the javascript way of getting the duration doesn't make any sense. For a live stream that started 2 hours ago, getCurrentTime() returns correctly 2*60*60=7200 when at the current time, but getDuration() returns 10245 for whatever reason.
I have a mp3 player in Delphi.
When the player is running and I change the audio output device, say from line out (speakers) to bluetooth, the player still "sends" the sound to the line out device.
When my bluetooth headset is connected and I start the player, everything is fine and the player "sends" the sound to the bluetooth device. But when I disconnect the bluetooth speakers/headset, the player doesn't play any song, it just skips every song as they won't be "playable".
Is there a way to get this managed?
Every other player, VLC, Winamp, Windows Media Player, are able to handle the change of the output device "on the fly".
For the player I use Delphi XE, but I think this isn't relevant to the problem as itself.
At the time I use BASS library 2.4.11
Thanks for your answers in advance!
MPage
Yes, there is the way.
AIMP player is exactly written in Delphi using BASS library.
If you stop playing, change audio output in preferences and start playing - it sends music to the newly selected sound device.
So, after reading some manuals and doing some test, this is what I have now in my "MediaPause" routine:
// Reset counter
i := 1;
// Reset device list
lstADevices.Clear;
while BASS_GetDeviceInfo(i, ADeviceInfo) do
begin
lstADevices.Add(ADeviceInfo.name);
inc(i);
end;
intDevice := -1;
for i := 0 to lstADevices.Count - 1 do
begin
if lstADevices[i] = 'Bluetooth A2DP Stereo Audio (Bose AE2w 01.02.00( Stereo ))' then
begin
intDevice := i + 1; // + 1 is important, because the list starts with 0! (for BASS 0 means 'no device')
BASS_GetDeviceInfo(intDevice, ADeviceInfo);
intFlag := ADeviceInfo.flags;
if intFlag = 67108868 then
begin
for j := 0 to lstADevices.Count - 1 do
begin
if lstADevices[j] = 'Speakers (Realtek High Definition Audio)' then
begin
intDevice := j + 1; // The list starts at 0
break;
end;
end;
end;
break;
end;
end;
BASS_Init(intDevice, 44100, 0, Application.Handle, nil);
blnBASS := BASS_ChannelSetDevice(AudioStream, intDevice);
if not blnBASS then
intBASSErrorCode := BASS_ErrorGetCode;
BASS_ChannelPlay(AudioStream, False);
When the program is started and the bluetooth headset is not connected, it will not be enumerated to get into the device list. So I have to enumerate the devices at any necessary time. I wanted to implement this into the "tick counter" for displaying the time (ticks in seconds), but because of the following behavior I didn't do so yet.
I can switch (BASS_ChannelSetDevice) between the bluetooth headset and the speakers once. When I want/have to switch again, to whatever reason, I get the error code 4 which means BASS_ERROR_BUFLOST (The sample buffer was lost).
I tried to find anything according the buffer size, but couldn't find anything.
I check the flag value 67108868 of the bluetooth device, because I couldn't find any other way to check if the device is available or not.
If the bluetooth device has been connected once during the runtime, it will always get enumerated even it is disconnected afterwards. It also has the "enabled" state, so I only found the difference in the flag value.
Packing the above code into the tick counter for the display I could get it managed to change the devices from speakers to headset automatically, which would be the "perfect" way for me, but due to the problem with the "buffer lost" error, I removed it from the tick counter routine.
Like Victoria and Arioch 'The mentioned, I paused the player before changing the device. Like mentioned, it works one time and the next time I run into the "buffer lost" error. This means, there is no error produced, but the output isn't changed then.
As I'm not sure if "my way" is correct in any sense, is there a "more safe" way to change the devices?
MPage
I using Delphi XE and DSPack 2.3.3.
I'm maintaining a desktop application with Webcam capture. The user is able to capture pictures of visitors and documents.
Everything is working fine. One of our largest customers is moving to Citrix 7.13 and the webcam is freezing.
Their support contacted Citrix and Citrix Engineering would like to know if the application is calling the IMediaFilter::SetSyncSource method to explicitly set the “reference clock” to the filter graph in their code regarding the webcam capturing.
I made a few test and in fact there's a call when the rendering starts. You can see the call when running DSPack demo "VideoCap":
// now render streams
with CaptureGraph as IcaptureGraphBuilder2 do
begin
// set the output filename
SetOutputFileName(MEDIASUBTYPE_Avi, PWideChar(CapFile), multiplexer, Writer);
// Connect Video preview (VideoWindow)
if VideoSourceFilter.BaseFilter.DataLength > 0 then
RenderStream(#PIN_CATEGORY_PREVIEW, nil, VideoSourceFilter as IBaseFilter,
nil , VideoWindow as IBaseFilter);
// Connect Video capture streams
if VideoSourceFilter.FilterGraph <> nil then
RenderStream(#PIN_CATEGORY_CAPTURE, nil, VideoSourceFilter as IBaseFilter,
nil, multiplexer as IBaseFilter);
// Connect Audio capture streams
if AudioSourceFilter.FilterGraph <> nil then
begin
RenderStream(nil, nil, AudioSourceFilter as IBaseFilter,
nil, multiplexer as IBaseFilter);
end;
end;
CaptureGraph.Play;
According to DSpack source comments:
{ The reference clock has changed. The filter graph manager sends this event
when its IMediaFilter.SetSyncSource method is called.}
property OnGraphClockChanged: TNotifyEvent read FOnGraphClockChanged write FOnGraphClockChanged;
And in fact OnGraphClockChanged gets fired after CaptureGraph.Play is called.
Is it possible to avoid calling SetSyncSource?
Do you know if this will solve this issue?
TIA,
Clément
Quoting the MSDN page on IMediaFilter::SetSyncSource:
When the graph runs, the Filter Graph manager calls this method on every filter in the graph, to notify them of the graph reference clock. Use this method to store the IReferenceClock pointer. Increment the reference count on the stored pointer. Before the filter is removed from the graph, the Filter Graph Manager calls SetSyncSource again with the value NULL.
This means that SetSyncSource() is called regardless of your code. If the filter you are using is stalling because of the filter graph calling it's SetSyncSource() method, then this seems like a defect in the filter.
In this case a potential workaround would be to create a wrapper filter around the capture filter in question and to forward all method calls except SetSyncSource(). But most likely the problem has other origin.
My bet is that setting the reference clock to NULL will solve the problem. To do this you have to query IMediaFilter interface from IFilterGraph and call SetSyncSource(NULL). This will disable the entire timing for the graph and render every multimedia sample as fast as it is generated.
More details on live source filter graphs can be found at this MSDN page - https://msdn.microsoft.com/en-us/library/windows/desktop/dd390645(v=vs.85).aspx
I've scoured the web, upgraded the player, rewritten it 5 times, and now completing my 5th day of failing, and still cannot accomplish what the folks at Longtail tell me will work. (Don't get me wrong, I love 'em there, but this has me ready to jump off a bridge).
I'm simply trying to load a video that will play with Flash or iOS, and upon loading it, immediately go to a specific point in the video useing the .seek() method. Longtail tells me to use the onBeforePlay() function because iOS apparently doesn't respect the start value of the playlist. This code works like smoke with Flash, but ignores the seek in iOS.
Can ANYone assist me with this - it has become the most expensive script I've ever worked on and I have made zero progress at all. :( :( :( Also, I removed all the console functions and tried that, but with the same result.
Full code/player can be seen at http://www.tempurl.us/jw6e.html. You can see that with Flash, the video starts at 60 seconds, but on iOS, it starts at 0.
jwp = jwplayer('jwp').setup({
title: 'Single File Player', width: '720', height:'240', autostart: 'false', listbar: {position: "right",size: 400},
sources:[
{ file: 'http://media3.scctv.net/insight/mp4:nursing_4_clips_400.mp4/playlist.m3u8'},
{ file: 'rtmp://fms.scctv.net/insight/nursing_4_clips_400.mp4'}
]
}
);
jwp.onReady(function() {
// Create a playlist item of the video to play
var newItem = [
{ title: 'Title4 ACUTE_ABDO_PAIN_400',
image: 'playlistitem.png',
sources:[
{ file: 'http://media3.scctv.net/insight/mp4:ACUTE_ABDO_PAIN_400.mp4/playlist.m3u8'},
{ file: 'rtmp://fms.scctv.net/insight/ACUTE_ABDO_PAIN_400.mp4'}
]
}
];
jwp.load(newItem);
});
jwp.onBeforePlay(function() {
// This Works on PC/Mac with Flash, but does nothing on iPad/iPhone
jwp.seek(60);
});
Simply to close the question, the bottom line on this problem was that iOS will not allow autostart - period. Knowing that, all the expected events that were not behaving as expected made sense. Once the user initiates the stream with Play, everything works as expected. In our case, this is still a problem because we want to start later in the stream, but knowing that made dealing with it more manageable.
If the problem is iOS will not allow autostart - period. Knowing that,
all the expected events that were not behaving as expected made sense.
Once the user initiates the stream with Play, everything works as
expected
then you can have a play button only for tablet and ios device and on Clicking the play button,
call jwplayer().play(), this could be a work around for your problem, and after you have invoked jwplayer.play, which is only possible with the touch event, after play is triggeredother events will work.
otherwise even if you try jwplayer().play() onReady(), or autostart nothing will work because of iOs will not allow autostart as you said
I've solved this problem on iOS using onBeforePlay with seek() and play(). This work on desktop flash and IOS. Doesn't work on Android using the parameter androidhls:true
jwplayer().onBeforePlay(function() { jwplayer().seek(60); });
jwplayer().play();
As Ethan JWPlayer mentioned in comment use onPlay event. To prevent "loop buffering" as you said just use flag variable:
var isFirstStart = true,
seekValue = 60;
jwplayer().onPlay(function(){
//exit if it's no first playback start
if( !isFirstStart ) {
return;
}
jwplayer().seek(seekValue);
isFirstStart = false;
});
I've been struggling with an elusive audio distortion bug using webkitAudioContext in HTML5 under iOS 6. It can happen in other circumstances, but the only way I can get 100% repro is on the first visit to my page after power cycling the device. It seems like if you visit any audio-capable page prior to visiting this one, the problem will not occur.
The distortion only happens to audio generated by webkitAudioContext.decodeAudioData() and then played through webkitAudioContext.createBufferSource(). Audio playback of webkitAudioContext.createMediaElementSource() will not distort.
Am I missing some initialisation step? Here's the code and HTML in its entirety that I submitted to Apple as a bug report (but have received no reply):
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var buffer = null;
var context = null;
var voice = null;
function load_music(file) {
context = new webkitAudioContext();
voice = context.createBufferSource();
var request = new XMLHttpRequest();
request.onload = function() {
context.decodeAudioData(request.response, function(result) {
buffer = result;
document.getElementById("start").value = "Start";
});
};
var base = window.location.pathname;
base = base.substring(0, base.lastIndexOf("/") + 1);
request.open("GET", base + file, true);
request.responseType = "arraybuffer";
request.send(null);
}
function start_music() {
if (!buffer) {
alert("Not ready yet");
return;
}
voice.buffer = buffer;
voice.connect(context.destination);
voice.noteOn(0);
document.getElementById("compare").style.display = "block";
}
</script>
</head>
<body onload="load_music('music.mp3')">
<p>This is a simple demo page to reproduce a <strong>webkitAudio</strong>
problem occurring in Safari on iOS 6.1.4. This is a stripped down demo
of a phenomenon discovered in our HTML5 game under development,
using different assets.</p>
<p><u>Steps to reproduce:</u></p>
<ol>
<li>Power cycle <strong>iPhone 5 with iOS 6.1.4</strong>.</li>
<li>Launch Safari immediately, and visit this page.</li>
<li>Wait for "Loading..." below to change to
"Start".</li>
<li>Tap "Start".</li>
</ol>
<p><u>Issue:</u></p>
<p>Audio will be excessively distorted and play at wrong pitch. If
another audio-enabled web site is visited before this one, or this
site is reloaded, the audio will fix. The distortion only happens on
the first visit after cold boot. <strong>To reproduce the bug, it is
critical to power cycle before testing.</strong></p>
<p>This bug has not been observed on any other iOS version (e.g. does
not occur on iPad Mini or iPod 5 using iOS 6.1.3).</p>
<input id="start" type="button" value="Loading..." onmousedown="start_music()" />
<span id="compare" style="display:none;"><p>Direct link to audio file, for
comparison.</p></span>
</body>
</html>
Note: The body text suggests this only occurs on iOS 6.1.4, but I mean to say that the problem only occurs upon power cycling in this situation. I've experienced the problem on the iPad Mini under 6.1.3, too, but not upon power cycling.
Edit: a few things I've tried... Deferring the creation of the buffer source makes no difference. Using different transcoders to generate the .mp3 file it plays makes no difference. Playing throwaway silence as the first sound makes no difference as the distortion continues for every decodeAudioData sound until the page reloads. If createMediaElementSource and createBufferSource sources are mixed in the same page, only the createBufferSource audio (using decodeAudioData) will distort. When I check the request.response.byteLength in the failure case and the non-failure case, they are the same, suggesting the XMLHttpRequest is not returning incorrect data, though I would think corruption of the data would damage the MP3 header and render the file unplayable anyway.
There is one observable difference between the failure condition and the non-failure condition. The read-only value context.sampleRate will be 48000 in the failure state and 44100 in the non-failure state. (Yet the failure state sounds lower pitch than the non-failure state.) The only thing that occurs to me is a hack wherein I refresh the page via JavaScript if 48000 is detected on a browser that should be reporting 44100, but that's serious userAgent screening and not very future proof, which makes me nervous.
I have been having similar problems, even on iOS 9.2.
Even without a <video> tag, playback is distorted when first playing audio on the page after cold boot. After a reload, it works fine.
The initial AudioContext seems to default to 48 kHz, which is where distortion is happening (even with our audio at 48 kHz sample rate). When playback is working properly, the AudioContext has a sample rate of 44.1 kHz.
I did find a workaround: it is possible to re-create the AudioContext after playing an initial sound. The newly-created AudioContext seems to have the correct sample rate. To do this:
// inside the click/touch handler
var playInitSound = function playInitSound() {
var source = context.createBufferSource();
source.buffer = context.createBuffer(1, 1, 48000);
source.connect(context.destination);
if (source.start) {
source.start(0);
} else {
source.noteOn(0);
}
};
playInit();
if (context.sampleRate === 48000) {
context = new AudioContext();
playInit();
}
I found a related bug with HTML5 video and think I discovered the root of the problem.
I noticed that if you play a video using a <video> tag, it sets the context.sampleRate value to whatever the video's audio was encoded at. It seems as if iOS Safari has one global sampleRate that it uses for everything. To see this, try the following:
// Play a video with audio encoded at 44100 Hz
video.play();
// This will console log 44100
var ctx = new webkitAudioContext();
console.log(ctx.sampleRate);
// Play a video with audio encoded at 48000 Hz
video2.play();
// This will console log 48000
var ctx = new webkitAudioContext();
console.log(ctx.sampleRate);
This global sample rate appears to persist across page loads and is shared between tabs and browser instances. So, playing a youtube video in another tab could break all your decoded audio.
The audio becomes distorted when it is decoded at one sample rate and played at another one.
Decode audio and store the buffer
Do something to change the sample rate, such as playing a video or audio file
Play buffer (distorted)
I don't know why it's happening after a cold start. If I had to guess, it's that Safari doesn't initialize this global sample rate until you try to use it.
The problem is still there on iOS 7, so I don't think a fix is coming anytime soon. We're stuck with hacks in the mean time like checking for a changed sample rate.
An npm package is online to fix this:
https://github.com/Jam3/ios-safe-audio-context
npm install ios-safe-audio-context