Streaming media learning notes --------- Code video preview

zhaozj2021-02-16  42

This article is complementary and perfect for the previously written "Showing the compressed and compressed video"

"Show the video before compression and compressed video" original text as follows:

To display the compressed and compressed video stream to use the IWMenCDataView interface. To add an IWMencDataView interface using the IWMenCDataViewCollection :: Add method.

Show the window before the encoding

The code is as follows: // Some basic settings are omitted.

IWMenCDataView * ppreview;

IWMenCDataViewCollection * ppreviewcoll;

HR = CoCreateInstance (CLSID_WMENCPREVIEW,

NULL,

CLSCTX_INPROC_SERVER,

IID_IWMENCDATAVIEW,

(void **) & ppreview);

// Retrieve The Preview Collection.

HR = pvidsrc-> get_previewCollection; & pPreviewColl;

LONG LCOOKIE = -1; // Set to -1, then the encoding will automatically add a unique cookie.

hr = ppreviewcoll-> add (ppreview, & lcookie);

HWND HWND; // A window handle, if there is no setting, a system window is automatically called.

HR = ppreview-> setViewSetting ((DWORD) LCOOKIE, SIZEOF (HWND),

(Byte *) & hw);

HR = Pencoder-> start ();

// Start Viewing The Stream in A Pop-Up Window.

HR = ppreview-> start (lcookie); // When the encoding is started, the window is displayed.

Show the encoded window

IWMenCDataView * PPostView;

IWMenCDataViewCollection * ppostviewcoll;

HR = CoCreateInstance (CLSID_WMENCPREVIEW,

NULL,

CLSCTX_INPROC_SERVER,

IID_IWMENCDATAVIEW,

(void **) & ppostview;

// Retrieve The Preview Collection.

HR = pvidsrc-> get_postviewcollection; & pPostViewColl;

LONG LCOOKIE = -1; // Set to -1, then the encoding will automatically add a unique cookie.

HR = PPOSTVIEWCOLL-> Add (ppostview, & lcookie);

HWND HWND; // A window handle, if there is no setting, a system window is automatically called.

HR = PPOSTVIEW-> SetViewSetting ((DWORD) LCOOKIE, SIZEOF (HWND),

(Byte *) & hw);

HR = Pencoder-> start ();

// Start Viewing The Stream in A Pop-Up Window.

HR = pPostView-> start (lcookie); // Start encoding, display the window.

The above is only explaining the settings of the display window, no file input and format selection, so you have to change the source code to control the open file, store the path, encoding format, and improve the program running interface as follows: two files Path separately with cstring m_path, m_path1

The implementation of the browsing button is as follows:

Cfiledialog file (true); // true To open a file, false is saving a file

File.domodal (); // Response Click event

m_path = file.getpathname (); // Get the full path to the file

this-> Updatedata (false); // Update data

Getdlgitem // enables the screen capture and the button of the video device, because file coding has been selected. This will make the program more robust, otherwise it is unintentionally in the middle of the two buttons to appear unexpected errors.

-> EnableWindow (FALSE);

Getdlgitem (IDC_DEvice)

-> EnableWindow (FALSE);

Cfiledialog File1 (false, "". Wmv ", null, OFN_HIDEREADOONLY, / / ​​Save a file, and with .WMV is extension

"WMV files (* .wmv) | * .wmv |");

File1.domodal ();

IF (m_path1 = file1.getpathname ())

Getdlgitem (IDC_COMBO)

-> EnableWindow (TRUE);

This-> Updatedata (false);

Where the encoded format is added to the window when the window is initialized, the custom function is called by cpreviewsdlg :: cho (); the custom function is called:

Void cpreviewsdlg :: choice ()

{

HRESULT HR;

IWMencoder * Pencoder;

IWMencProfileCollection * PProcoll;

IWMencprofile * PPRO;

Long Lcount;

INT I;

// Initialize the COM Library and Retrieve A Pointer

// TO an IWMencoder Interface.

HR = Coinitialize (NULL);

HR = CocreateInstance (CLSID_WMENCODER,

NULL,

CLSCTX_INPROC_SERVER,

IID_IWMENCODER,

(void **) & pencoder;

// Retrieve a Pointer to an IWMencProfileCollection Interface.

HR = Pencoder-> Get_ProfileCollection; & pProcoll;

// Loop THROUGH The Profile Collection and Retrieve A Specific

// Profile.

CString Str;

CCOMBSTR BSTRNAME (L "");

HR = PPROCOLL-> GET_COUNT (& LCOUNT);

For (i = 0; i

{

HR = PPROCOLL-> Item (I, & PPRO);

HR = PPRO-> GET_NAME (& BStrName);

Str = bstrname.copy ();

m_choice.insertstring (i, str);

}

Pencoder-> Release ();

And use the CCOMBOBOX class onselchangeCombo () to get the format of the selected encoded

Void cpreviewsdlg :: OnselchangeCombo ()

{

j = m_choice.getcurseel (); // assigns the current selection to J

The initial value of if (j! = 100) // j is 100, if not equal to 100, the format has been selected

GetDLGITEM (IDC_Start) // Make the start coding button is valid

-> EnableWindow (TRUE);

}

With regard to the difference between the screen and the device, H = 1 is the screen capture, H = 2 is a video from the device. The procedure is as follows:

Void cpreviewsdlg :: onscreen ()

{

H = 1;

Getdlgitem (IDC_DEvice)

-> EnableWindow (FALSE);

Getdlgitem (IDC_Brower)

-> EnableWindow (FALSE);

}

Void cpreviewsdlg :: ONDEVICE ()

{

H = 2;

Getdlgitem (idc_screen)

-> EnableWindow (FALSE);

Getdlgitem (IDC_Brower)

-> EnableWindow (FALSE);

}

When configuration is good, you can start encoding, the program is as follows:

Void cpreviewsdlg :: onstart ()

{

HWnd = :: getdlgitem (this-> getsafehwnd (), IDC_VIEW); // Get the handle of the pre-preview code before the window

phwnd = :: getdlgitem (this-> getsafehwnd (), idc_postview); // Get the handle of the preview encoded window

// g_mythread-> setParentWnd (hwnd); // can remove

g_mythread-> postthreadMessage (wm_start, 0, 0); // Send a message to the thread, start coding

Getdlgitem (idc_watch)

-> EnableWindow (TRUE);

Getdlgitem (IDC_STOP)

-> EnableWindow (TRUE);

Getdlgitem (IDC_Start)

-> EnableWindow (FALSE);

}

The start function in the thread is as follows:

Void CMYTHREAD :: OnStart (WParam WPARAM, LPARAM LPARAM)

{

IWMENCSOURCEGROUPCOLLECTION * PSRCGRPCOLL;

IWMENCSOURCEGROUP * PSRCGRP;

IWMENCSOURCE * paudsrc1;

IWMENCSOURCE * PSRC1;

IWMENCVIDEOSOURCE * PVIDSRC1;

// IWMenCDataView * ppreview;

IWMenCDataViewCollection * ppostviewcoll;

IWMenCDataViewCollection * ppreviewcoll;

IWMencProfileCollection * PProcoll;

IWMencSourcePluginInFomanAger * psrcplugmgr;

IWMencPluginInfo * PPluginfo;

IWMencprofile * PPRO;

IWMencDisplayInfo * pdispinfo;

IWMencattributes * Pattr;

IWMENCBROADCAST * PBRDCAST;

IWMencFile * Pfile;

WMENC_ENCODER_STATE ENUMENCODERSTATE; CCOMBSTR BSTRRESOURCE (L "");

Long Lcount;

Short I;

HR = Coinitialize (NULL);

HR = CocreateInstance (CLSID_WMENCODER, / / ​​Initialization COM)

NULL,

CLSCTX_INPROC_SERVER,

IID_IWMENCODER,

(void **) & pencoder;

// Retrieve a Pointer to An IWMencSourceGroupCollection

// Interface.

HR = pencoder-> get_sourcegroupcollection; & psrcgrpcoll;

// Add a Source Group to the collection. Named "SG_1"

HR = psrcgrpcoll-> add (l "sg_1", & psrcgrp);

// Add a video and audio source to the source group.

HR = psrcgrp-> addsource (wmend_video, & psrc1);

HR = psrcgrp-> addsource (wmenc_audio, & paudsrc1);

// Retrieve a Pointer to an IWMencVideSource Interface.

HR = psrc1-> queryinterface (IID_IWMENCVIDEOSOURCE,

(void **) & pvidsrc1);

IF (h == 0) // h = 0 Description is the encoding file

{

CCOMBSTR BSTRINFILE ("");

BStrinfile.Append (pthread-> m_path); // CString and CCOMBSTR transformation

HR = paudsrc1-> setInput (bstrinfile);

HR = pvidsrc1-> setInput (bstrinfile);

}

Else

{

HR = pencoder-> get_sourceplugininfomanager (& psrcplugmgr);

HR = psrcplugmgr-> item (0, & ppluginfo);

HR = PPLUGINFO-> Item (1, & bstrresource); // Set the input of sound

CCOMBSTR AUD (L "Device: //");

Aud.Append (BStrRRRESOURCE);

HR = paudsrc1-> setInput (AUD);

IF (h == 1)

HR = pvidsrc1-> setInput (l "screencap: // screen capture); // If h = 1, video source is the screen

Else

{

HR = psrcplugmgr-> item (1, & ppluginfo);

HR = PPLUGINFO-> Item (1, & bstrRRRESource);

CCOMBSTR VID (L "Device: //"); // Get input of video devices

Vid.Append (BStrRRRESource);

HR = pvidsrc1-> setInput (vid);

}

}

// Choose a profile from the collection.

CCOMBSTR BSTRNAME = NULL; CCOMVARIANT VARPROFILE;

Varprofile.vt = vt_dispatch;

HR = Pencoder-> Get_ProfileCollection; & pProcoll;

HR = PPROCOLL-> GET_COUNT (& LCOUNT);

For (i = 0; i

{

HR = PPROCOLL-> Item (I, & PPRO);

HR = PPRO-> GET_NAME (& BStrName);

IF (i == j) // Select the encoding format

{

// set the profile in the source group.

Varprofile.pdispval = ppro;

HR = psrcgrp-> put_profile (varprofile);

Break;

}

}

// Retrieve a Pointer to an IWMencdisplayInfo Interface.

HR = pencoder-> get_displayinfo (& PDISPINFO);

// Describe the encoded.

CCOMBSTR BSTRAUTHOR ("Let5Fly");

CCOMBSTR BSTRCOPYRIGHT ("Copyright 2000. All Rights Reserved.");

"" Description of the Encode Content. ");

CCOMBSTR BSTRRANG ("Content Rating.");

CCOMBSTR BSTRTILE ("Test The Encoder");

HR = pdispinfo-> put_author (bstrauth); // Description Information

HR = PDISPINFO-> PUT_COPYRIGHT (BSTRCopyRight);

HR = PDISPINFO-> PUT_DESCRIPTION (BSTRDESCRIPTION);

HR = PDISPINFO-> PUT_RATING (BSTRRATIN);

HR = pdispinfo-> put_title (bstrtitle);

// Retrieve a Pointer to an IWMencattributes Interface.

HR = Pencoder-> Get_attributes (& PATTR);

// add an attribute to the attributes collection.

CCOMBSTR BSTRATITRNAME (L "Datecreated:");

Ccomvariant Varvalue;

Varvalue.vt = vt_bstr;

VARVALUE.BSTRVAL = L "02/15/2000";

HR = Pattr-> Add (BstrattrName, VARVALUE);

// Retrieve a Pointer to an IWMENCBROADCAST INTERFACE.

HR = Pencoder-> get_broadcast (& pbrdcast);

// Specify a port number and a protocol.

HR = PBRDCAST-> PUT_PORTNUMBER (WMENC_PROTOCOL_HTTP, 527); // Set the broadcast port is 527 // Retrieve a Pointer to an IWMencfile Interface.

HR = Pencoder-> get_file (& pfile);

// Specify a file in which to save encode.

CCOMBSTR BSTRSAVEFILE ("");

bstrsavefile.append (pthread-> m_path1); // Store the encoded file

HR = Pfile-> PUT_LOCALFILENAME (BSTRSAVEFILE);

// Retrieve a Pointer to a Preview Object.

HR = CoCreateInstance (CLSID_WMENCPREVIEW,

NULL,

CLSCTX_INPROC_SERVER,

IID_IWMENCDATAVIEW,

(void **) & ppreview);

HR = COCREATEINSTANCE (CLSID_WMENCPREVIEW, // Initialization Preview Window, respectively

NULL,

CLSCTX_INPROC_SERVER,

IID_IWMENCDATAVIEW,

(void **) & ppostview;

// Retrieve The Preview Collection.

HR = PSRC1-> Get_PreviewCollection (& PPREVIEWCOLL);

HR = psrc1-> get_postviewCollection (& PPOSTVIEWCOLL);

// add the postiew Object to the data view collection. If you set the

// cookie to -1, the Encoder Engine Automatic or Generates a unique

// cookie.

hr = ppreviewcoll-> add (ppreview, & lcookie);

HR = PPOSTVIEWCOLL-> Add (PPostView, & lcookiePostView);

// Continue configuring the encoder engine.

HR = Pencoder-> PreparetoEncode;

HR = ppreview-> setViewSetting ((DWORD) LCOOKIE,

SizeOf (hwnd),

(Byte *) & hw);

HR = PPOSTVIEW-> setViewSetting ((DWORD) LCOOKIEPOSTVIEW, // Set video input

Sizeof (phwnd),

(Byte *) & phwnd);

HR = Pencoder-> start ();

AfxMessageBox ("Encoder Have Start!");

// hr = ppreview-> start (lcookie);

// Wait Until The Engoder Engine Stops Before Exiting The Application.

// you can do this by using the _iwmencoderevents object to create an

// Event Sink.

HR = Pencoder-> get_runstate (& Enumencoderstate); // Get running status}

among them

HRESULT HR;

IWMencoder * Pencoder;

IWMenCDataView * ppreview;

IWMenCDataView * PPostView;

Long lcookie = -1;

Long LcookiePostView = 2;

Both are defined as global variables because it is also used in other functions.

Send a message to the WATCH () function in the thread when you want to watch the video.

Void cpreviewsdlg :: onwatch ()

{

// w = 2;

g_mythread-> postthreadMessage (WM_WATCH, 0, 0);

}

The Watch () function determines that the value of the global variable W is to show the encoded or the encoded video, the program is as follows:

Void CMYTHREAD :: Watch (WPARAM WPARAM, LPARAM LPARAM)

{

IF (w == 1)

HR = ppreview-> start (lcookie);

Else

HR = ppostview-> start (lcookiepostview);

AfxMessageBox ("Have Previwe!");

}

The last thing to explain is that the thread is created when the window is initially, and the window handle is obtained via gethWnd (). (Because it is necessary to use its variables and functions in the CMYTHREAD class)

g_mythread = (cmythread *) AFXBEGINTHREAD (Runtime_Class (CMYTHREAD), 0, 0);

g_mythread-> gethwnd (this);

The implementation of gethwnd () is as follows:

CPREVIEWSDLG * PTHREAD;

Bool gethwnd (CPREVIEWSDLG * PMAIN)

{

Pthread = PMain;

Return 1;

}

The preview program of the encoding video is over, it may be a bit chaotic, if you want a program, please contact me to let5fly@msn.com.

转载请注明原文地址:https://www.9cbs.com/read-25990.html

New Post(0)