开发者

How Can I Hook a Youtube Video (Flash Player?) To Slow Down Playback?

The only good software I know which can decelerate and accelerate the playback of a YouTube video in any browser without first downloading it (because that would be cumbersome), is Enounce MySpeed.

Unfortunately, this software is not free, and my trial version ran out. I was playing around with its registry settings and noticed a few keys:

ProgramsToHook: iexplore.exe;firefox.exe;plugin-container.exe;chrome.exe;safari.exe;opera.exe;maxthon.exe;feeddemon.exe;realplay.exe;flvplayer.exe;flv player.exe;flock.exe;adobe media player.exe
UseFlashAdapter: 1
LLModules: ole32.dll;nspr4.dll;chrome.exe;realplay.exe;objb3201.dll;oleaut32.dll;rpflashplayer.dll
ModulesToIntercept: flash10*;flash9*;npswf32.dll;gcswf32.dll;fldbg10*;flashplayer.3.1.1k.ocx;adobe media player.exe

Based on the names and values of these registry keys, I'm guessing the MySpeed software hooks some function(s) in the listed modules (but modules are or aren't the same as DLLs?..) and does so for each process listed in ProgramsToHook. This is what I don't understand. What is the concept of the MySpeed software. Obviously it's hooking something, but I'm not too familiar with the intricacies of Windows hooks so I came to ask you experts. I'm thinking if I can understand how this 开发者_C百科hook process works, I can make my own version of the software using EasyHook, which is a fantastic .NET library to perform user-mode and kernel-mode hooks.

I thought that Windows user-mode hooking goes something like this. You choose one function in one DLL, and you intercept that function (a.k.a hook) in one process you want. If you want to hook the DLL in multiple processes, you just have to repeat the procedure for each process.

And then kernel-mode hooking is just choosing one function in one DLL and intercepting that function in every process that calls it (hence kernel-mode). But surely there are tons of ways to hook; I'm not too sure on whats the difference between these two hooks and DLL injection either.

So the point is, I'd like to know how MySpeed works. What is their hooking concept? If I can know this then I can make such a software in .NET!

Thanks in advance.


I can't provide you with an accurate explanation as I don't know the API calls or capabilites, but it goes something like this: You app looks for iexplore.exe where it intercepts calls to certain modules. The module is mainly flash player. Flash has support for playing the video slower so you modify the call from iexplore.exe (JavaScript play button on webpage) or make an additional call to set playback speed.

What you need to do:

  • Use this tool to check what is actually happening: http://www.nektra.com/products/deviare-api-hook-windows/
  • Learn how to ask Flash Player to slow down a video (probably in Flash API docs). One Simple approach could be to see what MySpeed is actually doing using the Deviare API hook tool.
  • Write a program that replicates this procedure. It involves intercepting messages sent from one handle (iexplore.exe) to another (flash .dll). This can't be done externally, it has to be done internally, so this may be of help: http://www.codeproject.com/KB/threads/winspy.aspx

On hooks: http://msdn.microsoft.com/en-gb/library/ms644960.aspx

I don't think many people has done this in C#, so it could offer a challenge. I would though be interested in the progress (obstacles) if you have a blog or something to share the gory details on. :)

EDIT: The Deviare API Hook software seems not only to spy on calls, but also allow you to intercept them. So its a all-in-one package for your needs. :)
EDIT2: Relevant question: How do I intercept messages being sent to a window?


The key to speeding up or slowing down a video is to convince multimedia players that your computer is slower or faster than it really is. This can be accomplished hooking timeGetTime().

This is an extremely easy C# code to accomplish it:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Nektra.Deviare2;


namespace DeviareTest
{
    public partial class Form1 : Form
    {
        private int nSpeed;
        private uint nTime;

        private NktSpyMgr _spyMgr;

        public Form1()
        {
            InitializeComponent();

            _spyMgr = new NktSpyMgr();
            _spyMgr.Initialize();
            _spyMgr.OnFunctionCalled += new DNktSpyMgrEvents_OnFunctionCalledEventHandler(OnFunctionCalled);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            NktHook hook = _spyMgr.CreateHook("WINMM.dll!timeGetTime", (int)(eNktHookFlags.flgOnlyPostCall));
            hook.Hook(true);

            bool bProcessFound = false;
            NktProcessesEnum enumProcess = _spyMgr.Processes();
            NktProcess tempProcess = enumProcess.First();
            while (tempProcess != null)
            {
                if (tempProcess.Name.Equals("iexplore.exe", StringComparison.InvariantCultureIgnoreCase) && tempProcess.PlatformBits == 32)
                {
                    hook.Attach(tempProcess, true);
                    bProcessFound = true;
                }
                tempProcess = enumProcess.Next();
            } 

            if(!bProcessFound)
            {
                MessageBox.Show("Please run \"iexplore.exe\" before!", "Error");
                Environment.Exit(0);
            }
        }

        private void OnFunctionCalled(NktHook hook, NktProcess process, NktHookCallInfo hookCallInfo)
        {
            nTime++;

            if (nSpeed==-2)
                hookCallInfo.Result().LongVal = hookCallInfo.Result().LongVal - (int)(nTime * 0.2);
            else if(nSpeed==2)
                hookCallInfo.Result().LongVal = hookCallInfo.Result().LongVal + (int)(nTime * 3);
        }

        private void SlowButton_CheckedChanged(object sender, EventArgs e)
        {
            nSpeed = -2;
        }
        private void FastButton_CheckedChanged(object sender, EventArgs e)
        {
            nSpeed = 2;
        }
    }
}

I just published an article with a code example showing how to do this with the Deviare hooking engine. The sample code only works with the video part (not audio) and it is available here.


Youtube now has an html5 player with playback speed controls.

All you have to do is enable html5 here http://www.youtube.com/html5 Only some of the videos support the html5 player yet, though.

Hope this helps.


The key to speeding up or slowing down a video is to convince multimedia players that your computer is slower or faster than it really is

manipulating the system time will be a VERY dangerous and idiotic thing to do - not only will you break user-mode threadslices and hence have a serious impact on system-performance but you also will break many logging-functionalities and even user-mode reflectors which control KM-drivers ... this could both crash and physically harm (!) your system because modern hardware is programmable, given the correct (& proprietary, of course) set of func-calls and such. I would highly advise to NOT do reproduce this, even a few AV-apps will intercept this because of its dangerous nature.

But you're somewhat lucky : the kernel uses its own time, synced to hardware so windows itself COULD remain stable for a limited amount of time.

I think you should get back to the drawing-board, manipulating essential structures of your operating-system certainly is not the right way to accomplish your goal.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜