Direct的一个Online LiveTV项目

很赞!!!

link:  http://www.codeproject.com/KB/audio-video/TVToolbar.aspx

TV Toolbar Plays TV Shows - Internet Television Has Arrived - Part I

TV Toolbbar

Introduction

I wrote the first TV Toolbar that played video in any browser back in 1997 and I have created many versions of my TV Toolbar every year since then for both Internet Explorer and all the Mozilla Browsers like FireFox. Back in 1997, the TV Toolbar played video in any window by grabbing the handle to that window and playing recorded files using DirectShow. As time went by, more and more TV stations and independent producers began to stream their TV shows from video servers all over the world and I began using VLC to play live TV shows from streaming servers and web cams.

I started to write one article that included both the code for the TV Toolbar and the code for a VLC wrapper in C++ to play video streams but I quickly realized that the article would be too large so I decided to divide the article into 2 Parts, namely, Part I, dealing with creating just the TV Toolbar in Visual Studio 2008 and Part II, adding the code to the TV Toolbar for playing video from the many sources of TV shows that are now live on the Internet using a C++ wrapper for VLC. I had posted the source code for just the TV Toolbar in Visual Studio 6.0 and a lot of people asked me for the toolbar code in Visual Studio 2008 which is included in the source code for this article along with many new things. In Part II, I will add the source code for playing streaming video and go into a discussion of the various methods you can use to play streaming video from TV and radio sources and how to find these sources on the Internet which isn't as easy as you might think.

How The TV Toolbar Plays Live TV in Your Browser

There are three main ways to play video streams using either DirectShow, VLC, or Apple's Quicktime. I have used all three of these methods in various versions of my TV Toolbar. The best method on Windows, in my experience, is VLC, i.e. VideoLan, using a wrapper for the libvlc.lib library in either C++, C#, or Java and running that wrapper in a separate process from the TV Toolbar or whatever program you use to launch it. I have written a number of Camera Walls for streaming I.P. cameras and in the real world large companies expect your camera wall to run for over a month without crashing. The secret to preventing crashing of a camera wall is to NOT place the code for playing video inside the camera wall. Instead you create an executable that just plays video and launch that executable in its own process so that if it crashes, your camera wall is still up and running. The camera Wall is just a collection of windows where you stream the video into each window from a separate process. But to actually create truly separate instances of the VLC library, you must modify the source code for VLC in several ways including adding code that adds a Display Time Stamp to all RTSP streams. The source of TV shows the TV Toolbar uses are published video servers streaming TV shows and video and music, and files posted by the copyright holders of pre-recorded shows. More and more TV stations are putting part of their programming online either as live feeds or recorded video. In Part II of this article, I will show you how to find the I.P. addresses for sources of the thousands of TV and radio servers that you can stream TV shows and radio from online.

WARNING: The TV Toolbar will NOT play any P2P sources of video because in my opinion, that may be illegal and unethical without the permission of the copyright holder. There are hackers who record TV shows and post them on P2P nets but this is a violation of the owner's copyright and the quality is terrible. Stay away from P2P programs that claim to offer TV shows or you may find that your Internet service has been terminated by your provider and your name reported to one of several groups filing lawsuits for copyright infringement like with illegal music downloads.

Creating The TV Toolbar in VS2008 with A WebBrowser in a WebBand

One of the things that made my TV Toolbar so different back in 1997 and now is the fact that I decided to embed a WebBrowser control in a toolband and make my TV Toolbar an ordinary HTML web page. This allowed me to have dozens of toolbars loaded in one single toolband at the same time. In this version in Visual Studio 2008 I also put a WebBrowser control in a toolband but I separated the code so that you can easily add a regular toolbar and switch dynamically between HTML toolbars and a hard coded ATL/WTL C++ toolbar.  By using this approach, the TV Toolbar can display anything from cool buttons to stock quotes instantly from any remote server in any language including Japanese and Chinese. Users can also customize the TV Toolbar any way they want because the TV Toolbar is just a web page loaded inside of a webbrowser placed inside of an horizontal toolbar in Internet Explorer. While there are plenty of examples of hosting the WebBrowser control in Vertical bands inside of Internet Explorer, I decided to host the WebBrowser control inside of a Horizontal toolbar in Internet Explorer and run 2 sinks, one sink for events in the toolbar and another sink for events in the main browser window. There are many advantages to placing a browser inside of a toolbar to create the User Interface of the toolbar. The main reason is that the toolbar itself can reside on a remote server and be dynamically updated with new features, functionality and advertising instantly from a remote web server which includes things like streaming stock quotes, video, etc. in any language that can then be displayed in a variety of ways to the user. Another reason is that the webbrowser can take advantage of DHTML and Java to create spectacular User Interfaces inside of the toolbar. Shown below is my first TV Toolbar in 1997. Notice the "TV Toolbar" at the top of the browser.

TV Toolbbar

I decided to add the code for my TV Button shown below that installs as a separate DLL. When you click this button, you will see a dropdown menu that allows you to play videos INSIDE Internet Explorer using DirectShow. However, while this is okay for demonstrating the concept of playing video in a Browser window by getting the handle to the window, DirectShow or a VLC wrapper needs to run from a separate process in order to stream TV shows and have the system work well as I will cover in Part II of this article. Notice the HTML media control buttons I added to the TV Toolbar--right now they don't do anything but in Part II of this article I will add in the code that will communicate with a separate VLC wrapper for the latest version of VLC to play any form of video anywhere in any window on your computer. My idea was to create a website, www.tv-toolbars.com, that displays an updated list of TV and radio stations and you would drop the links from the web page right onto the white area on the right of these media controls to play that TV station. For example, in Part II of this article I will add a page to the website, www.tv-toolbars.com/tvshows.aspx, and put a list of TV stations on the web page with the I.P. address in the link on the web page, then a user can drag that link from the web page and drop it on the TV Toolbar in the white area to the right of the media controls and the TV Toolbar will then launch in a separate process the VLC wrapper and pass it the I.P. stream to play as shown below in "TV Links Drop Zone":

TV Toolbbar

A Different TV Toolbar for Each Tab

I decided to create a different instance of the TV Toolbar for EACH Tab in Internet Explorer which allows you to have a different TV Toolbar loaded for each tab as shown below. If you look at the source code, you will see that the class CWBToolbar is the class that manages the WebBrowser control interfaces and I create a separate instance of this class for each new tab created in Internet Explorer 7 & above. I left out the classes for connecting to a webservice to retrieve new toolbars and new TV and radio sources but I will add those classes back in Part II of this series of articles. In Part II, I will show you how to add a data management class, namely, CTVData, that we will maintain only one instance of to share the data between all tabs. CTVData will wrap shared memory to provide real time updates of data between multiple instances of the browser as well as the tabs. But I thought all that was too much code to discuss in Part I of this series of articles. And in Part II I will show you how to add a worker thread to handle all timer processing as well as fetching data from a web server as needed. This must be done in a thread and NOT using a WM_TIMER message because we're accessing Internet Explorer's message loop, and doing it in an message handler would hang the browser by freezing the message pump for the duration of the interaction over the internet. In fact, a thorough discussion of using a web service to retrieve TV data is fairly complex and I may write a Part III to this article series just to discuss all the complex issues involved. For example, timeout values should be stored in shared memory, so the locks are maintained there as well via member variables with an internal critical section which is higher performance than a named mutex in any toolbar calling a webservice.

There are no limits to the number of different TV Toolbars you can load so on one tab you might have the TV Toolbar for watching a TV show and on another tab you might have the Nerds TV Toolbar for developers as shown below:

TV Toolbar

TV Toolbar

Getting Things in Focus in The TV Toolbar

One usually experiences keystroke issues associated with hosting the WebBrowser control in an Explorer band which often cause problems with the backspace and delete keys when focus is set to an edit box by clicking on it with the left mouse button. These problems are caused if Internet Explorer does not know that the band currently has the focus. In order to alleviate these problems, I implement IOleControlSite. In the IOleControlSite::OnFocus method, the WebBrowser's IInputObjectSite::OnFocusChangesIS is called to tell the WebBrowser control who has the focus. So when the user presses a key, several things occur:

  1. The IInputObject::HasFocusIO method is called to see if WBToolBar currently has the focus. 
  2. The IInputObject::UIActivateIO method is called to tell WBToolBar that is being activated. 
  3. The IInputObject::TranslateAccelerator method is called. It is here that WBToolBar passes the keystroke to the hosted WebBrowser control. This causes accelerator keys such as backspace and delete to be processed.

To be certain that navigation will occur in the correct window, WBToolBar sinks events for all anchors on the page through the "all" collection when a page is loaded, so when a marked anchor is clicked, the target of the navigation is changed from the band window to the main browser window.

Navigation in TV Toolbar vs. Main Browser & Anchors

I cause navigation to occur in the correct window in a number of ways. When a page is loaded, the toolbar sinks events for all anchors on the page through the "all" collection. When an anchor is clicked, the target of the navigation is changed from the band window to the main browser window. I used a fragment identifier (i.e., bookmark) like "#_tbload" to navigate to the TOOLBAR and replace it with a new toolbar from any remote server.

Since our toolband will contain multiple instances of our webbrowser control and we will have multiple tabs in Internet Explorer 7 and above, we need to control which window navigation will occur in. There are other ways to accomplish this but this approach is simple and has worked well in the many TV Toolbars I have sold since 1997.

When a toolbar link is clicked, it will automatically navigate inside the band window so we sink events for all anchors in the toolbar's HTML file and look for an anchor passed in the URL in the BeforeNavigate2 event handler so we can determine whether to navigate inside the toolband or the main browser. In the TV Toolbar to control which window navigation will occur in, we sink events for all anchors on page. We navigate in the main window if an anchor is clicked. To determine where we want navigation to occur, we use in our URL an indicator known as a fragment identifier (otherwise known as a bookmark). We can't use the TARGET attribute because it causes Internet Explorer to open the link in a new window. We have defined the following anchors:

#define TB_SHELL "#_tbshell" 	// Launch a program file (.exe)
#define TB_LOAD "#_tbload" // Load the given toolbar .htm file
#define MB_LCHM "#_mblchm" // Load chm file into main browser
#define TB_LCHM "#_tblchm" // Load chm file into toolbar
#define IE_OPTION "#_option" // Show Options Dialog

Loading Anchors

If the anchor ("#") is omitted from the URL, then the link will be loaded into the main browser window below the TV Toolbar. For example, the following link in an HTML TV Toolbar .htm file would load the "www.yahoo.com" web page into the main browser as follows:

<a href="www.yahoo.com/">

To load a new HTML TV Toolbar, i.e., tvtoolbar.htm, as a toolbar you would include the anchor in the link as follows:

<a href="tvtoolbar.htm#_tbload">

Adjust Initial Height of the TV ToolBar at Launch

The HEIGHT of the TV Toolbar is automatically set at 26 PIXELS which is perfect for most toolbars. But you can control the height of the TV Toolbar and make it any value from 10 pixels to 100 pixels. To control the HEIGHT of the TV Toolbar from the hypertext script for the toolbar, say to set it at 36 PIXELS, you would use the following code between the <TITLE> tags as follows:

<TITLE>TBARV:36</TITLE>

And in the DISPID_DOCUMENTCOMPLETE event, we set the height of the TV Toolbar dynamically as follows:

case DISPID_DOCUMENTCOMPLETE:
{
USES_CONVERSION;
CString strUrl = "";
if (_pWebBrowserOC) {
BSTR bstrUrl;
_pWebBrowserOC->get_LocationURL(&bstrUrl);
strUrl = CString(bstrUrl);
IDispatch *pDispatch = NULL;
if (SUCCEEDED(_pWebBrowserOC->get_Document(&pDispatch)) && pDispatch) {
try {
IHTMLDocument2 *pDoc = NULL;
if (SUCCEEDED(pDispatch->QueryInterface(IID_IHTMLDocument2,
(void**)&pDoc)) && pDoc) {
try {
CString csTitleData = "";
CString csID = "";
CString csHeight = "";
// SET HEIGHT OF TOOLBAR FROM <TITLE>TBARV:36</TITLE>
BSTR bstTitle = NULL;
if ( SUCCEEDED( pDoc->get_title(&bstTitle) ) ) {
csTitleData = (CString)bstTitle;
AfxExtractSubString(csID, csTitleData, 0, (TCHAR)':');
AfxExtractSubString(csHeight, csTitleData, 1, (TCHAR)':');
if ( ( csID == "TBAR" ) || ( csID == "TBARV" ) ) {
LONG lTempHeight = 26;
lTempHeight = atoi(csHeight);
if ( ( lTempHeight > 10 ) && ( lTempHeight < 100 ) ) {
_lBandHeight = lTempHeight;
} else { _lBandHeight = 26; }
if ( csID == "TBARV" ) _bBandVarH = TRUE;
} else { _bBandVarH = FALSE; _lBandHeight = 26; }
// MAKE SURE WE HAVE THE TOOLBAR!
IOleCommandTarget* pCmdTarget;
if (SUCCEEDED(_pSite->QueryInterface(IID_IOleCommandTarget,
(LPVOID*)&pCmdTarget))){
pCmdTarget->Exec(&CGID_DeskBand, DBID_BANDINFOCHANGED,
OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL);
pCmdTarget->Release();
}
}
} catch(CException* pe){ pe->Delete(); }
}
} catch(CException* pe){ pe->Delete(); }
}
}

Creating HTML TV Toolbars

The sample TV Toolbars included in the source code with this article have TV Toolbars made in a number of different ways. Some of the TV Toolbars us a Java Applet to create cool-looking buttons with great colors and 3-D appearances. With a Java applet menu, the dropdowns will overlap the browser window which is a requirement. If you create a web page to use as a menu and don't want to use a Java applet, then you can use a Microsoft PopUp Object to create the toolbar and the dropdowns will overlap the browser window as required. It is pretty easy to create your own HTML toolbars in a few minutes to replace the ones in this sample. Toolbars can reside on the local client machine or a remote web server and can be almost anything: text files, .htm file, .chm files, ASP, JSP, etc. You can load web toolbars that reside on remote servers by just loading their URLs or you can use the Launcher Program or a DLL you create to retrieve web toolbars from remote servers and then stream those toolbars to a file on the client machine and load the files saved from the remote server from the client side which helps to bypass security problems on intranets. I included support for loading .chm files which can be easily expanded to search for all of the .htm files in the .chm file.

You can add as many toolbars as you want. For example, in the sample TV Toolbar with this article, I added the following TV Toolbars that you can dynamically switch between from any toolbar to another toolbar through the dropdown menu as follows:

TV Toolbbar

Launch Programs From The TV ToolBar

Launch a program file (.exe) by using the #_tbshell" anchor in your URL as follows:

#_tbshell#killer.exe#   This will launch the killer.exe file.

The NSIS Installer & Launching The TV Toolbar

I prefer using NSIS because, in my opinion, it is vastly superior to all the other installers like Microsoft, InstallShield, and WISE. The NSIS installation script is included. In order to add a Desktop link that users could use to launch the TV Toolbar I included a program called, TVTool, that is used to launch the TV Toolbar and make sure it is loaded into Internet Explorer as a toolbar. Microsoft's example of how to launch a toolbar is incorrect. You MUST pass "&vtEmpty" and NOT "0" as the last parameter as follows:

// Display Explorer ToolBar
VARIANT vtBandGUID, vtShow;
vtBandGUID.vt = VT_BSTR;
vtBandGUID.bstrVal =
SysAllocString(OLESTR("{5D570CA3-3123-11D5-B8D0-D2E7CAE90E45}"));
vtShow.vt = VT_BOOL;
vtShow.boolVal = true;
// You MUST pass "&vtEmpty"
and NOT "0" as last parameter!
m_pBrowserApp->ShowBrowserBar(&vtBandGUID,
&vtShow, &vtEmpty);
SysFreeString(vtBandGUID.bstrVal);
dispIE.m_lpDispatch->Release();

This launcher program includes a method LauchIEBrowser(), to launch an instance of Internet Explorer and a method, Register(), to register the DLL without using "regsvr32.exe" which may not be present on the user's computer.

The installer installs the TV Toolbar in C:\\Program Files\TVToolbar\TVToolbar.dll.
The "toolbars" directory in the nsis folder must be in the "TVToolbar" directory so that the toolbar can find the .htm toolbars and images.
I would suggest you run the compiled file, itvtoolbar.exe, in the nsis folder to install the toolbars, HTML files, and images in the correct directories.

In Conclusion

In the next week or two, I will post Part II of this article series that will focus on playing from a wide variety of sources. In the versions of the TV Toolbar I have released, I have primarily used either DirectShow or VLC. To use DirectShow, you need to write a DirectShow Source Filter for RTSP which I did which works but you still want to use the fantastic Demuxer in VLC even if you use DirectShow. You can modify the source code in VLC fairly easily to add a DirectShow Source Filter inside VLC and recompile VLC. The easiest way to compile VLC on Windows is to use Unbuntu on a memory drive. I will go into all of this in Part II. And to prevent locking up the browser, you must run play the video stream in a separate process that the TV Toolbar communicates with through one of several different methods.

I have written a lot of VLC wrappers in C++ (managed & unmanaged code) and C# .NET and I have tweaked one of them for this TV Toolbar in Part II of this article. I temporarily put some images into the TV Toolbar for play, stop, pause, etc. buttons and I will add the comments to hook them up in Part II of this article.

Bill SerGio
tv-toolbars.com

History

  • 12th May, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Bill SerGio, The Infomercial King

%7B757D8E82-7049-4342-97A0-B7D15C60EAB7%7D.gif
CEO
http://www.CutlerBayTV.com
United States United States

Member
I am an investor and I launch new companies using infomercials, www.GeminiGroupTV.com. An infomercial can gross from $60 million to $300 million in less than one year in TV sales. I put Spots and infomercials on National TV where I only pay the TV stations a percentage of my sales. www.StationBreak.net
 
My company is a pioneer in Data Mining going back to 1984.
We cross reference the Census Database and the Political Action Committee(PAC) Databases with your customer database and generate 376 additional pieces of information about your each of your customers. We then segment your customers into Targeting Niches and provides you with a list of products that we know will sell to each of those targeted lists.
 
Bill SerGio
www.SpyWhacker.com

转载于:https://www.cnblogs.com/msopengl/archive/2011/10/18/2216538.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,作为AI语言模型,我无法编写实际的安卓应用程序。但我可以给您一些基本的指导和思路,帮助您了解如何连接WIFI-Direct。 首先,您需要在Android应用程序中实现WIFI-Direct连接的基本功能。这包括以下步骤: 1. 检查设备是否支持WIFI-Direct。您可以使用WifiP2pManager类来检查设备是否支持WIFI-Direct,如下所示: ``` WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); if (manager != null && manager.isWifiP2pSupported()) { // WIFI-Direct is supported } else { // WIFI-Direct is not supported } ``` 2. 初始化WIFI-Direct。您需要创建一个WifiP2pManager对象和一个WifiP2pManager.Channel对象,用于与WIFI-Direct框架进行通信。您可以在Activity的onCreate()方法中执行此操作,如下所示: ``` WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); WifiP2pManager.Channel channel = manager.initialize(this, getMainLooper(), null); ``` 3. 执行WIFI-Direct扫描。您可以使用WifiP2pManager.discoverPeers()方法执行WIFI-Direct扫描,以查找其他设备。您可以在Activity中创建一个BroadcastReceiver对象,以侦听WIFI-Direct扫描结果。您需要在AndroidManifest.xml文件中添加以下权限: ``` <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> ``` 以下是执行WIFI-Direct扫描的示例代码: ``` manager.discoverPeers(channel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { // WIFI-Direct discovery started successfully } @Override public void onFailure(int reason) { // WIFI-Direct discovery failed } }); // Create a BroadcastReceiver for WIFI-Direct scan results private BroadcastReceiver wifiDirectReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { // WIFI-Direct peers changed WifiP2pDeviceList devices = intent.getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST); // Get a list of available devices and update the UI accordingly } } }; // Register the BroadcastReceiver to receive WIFI-Direct scan results IntentFilter filter = new IntentFilter(); filter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); registerReceiver(wifiDirectReceiver, filter); ``` 4. 连接到其他设备。一旦您发现了其他WIFI-Direct设备,您可以使用WifiP2pManager.connect()方法连接到它们。您需要在Activity中创建一个BroadcastReceiver对象,以侦听连接状态更改。以下是连接到其他设备的示例代码: ``` WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = device.deviceAddress; manager.connect(channel, config, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { // WIFI-Direct connection started successfully } @Override public void onFailure(int reason) { // WIFI-Direct connection failed } }); // Create a BroadcastReceiver for WIFI-Direct connection status changes private BroadcastReceiver connectionReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { // WIFI-Direct connection status changed NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); if (networkInfo.isConnected()) { // Connected to a WIFI-Direct device } else { // Disconnected from a WIFI-Direct device } } } }; // Register the BroadcastReceiver to receive WIFI-Direct connection status changes IntentFilter filter = new IntentFilter(); filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); registerReceiver(connectionReceiver, filter); ``` 以上是连接WIFI-Direct的基本步骤。当然,实际的应用程序可能需要更多的功能和用户界面元素,但这些步骤可以帮助您了解如何使用WIFI-Direct连接设备。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值