Windows Media Encode 9 編碼

因爲原公司一哥們,想要把avi格式的視頻文件轉爲wmv3編碼規範的wmv視頻,因爲他是搞java的所以想讓我幫着調查一下,然後我就答應了,然後我調查了一天發現真他媽的坑,網上幾乎沒有啥資料,這個wmEncoder也太古老了吧,編譯還是vc6.0,操作系統還是xp,win7還是優化後才支持,更無奈的是,官網所有資料都已下架,唯一搜到的到的資料不是要積分就是要會員,要麼下載下來驢脣不對馬嘴,尷尬的很,經過兩天的糾結,終於把資料下載完成,終於搞定,下面介紹一下過程,防止大家走彎路,以備參考,文後會附上相關資料(重點是資料要下對)。

一、安裝WMenCoder

  • wmencoder.zip Windows Media Encoder SDK是基於wmencoder這個軟件的SDK(32位,64位根據需求下載),所以你必須安裝這個軟件才能進行二次開發,在win10上安裝,一致彈出如下的錯誤:

因爲這個東西實在太古老了,古老到沒有人維護了,最好的辦法解決就是解壓這個exe文件,解壓後你會得到一個msi文件,通過這個文件進行安裝,如下圖

安裝成功後,你就會在開始菜單中看到windows media一欄,打開下面的Windows Media Encoder x64 Edition程序,就可以進行相關操作了,如下圖:

想一下,其實因爲是二次開發,所以基本上這個軟件能做的事情,二次開發都可以搞定。所以有什麼需求的話就可以先看看這個軟件能不能滿足,能夠滿足就可以接下來進行二次開發了。

調查發現此軟件轉化avi視頻爲wmv3格式文件,很輕鬆就完成了,ok!調查完畢,基礎環境搭建完成,接下來就是要調查如何進行二次開發編碼了。

二、安裝WMenCoder SDK

WMEncoderSDK.exe,毋庸置疑安裝了SDK才能進行代碼開發,同樣的在win10上直接運行exe文件,安裝失敗,還是需要通過解壓得到msi文件進行安裝,安裝成功後,就可以創建編碼工程了,以C++爲例。

  1. 創建vs2015工程(vs版本都可以),自己喜歡的工程類型,控制檯或對話框的mfc無所謂,測試下我喜歡用mfc的基於對話框的程序,在工程中添加引用頭文件目錄,如下圖所示:

2.接下來就可以編碼了,包含頭文件#include <wmencode.h>,將c盤下a'vi文件轉爲wmv文件,主函數代碼如下:

include <windows.h>
#include <wchar.h>
#include <atlbase.h>
#include "wmencode.h"
void Encoderfun()
{
	// Declare variables.
	HRESULT hr;
	IWMEncoder* pEncoder;
	IWMEncSourceGroupCollection* pSrcGrpColl;
	IWMEncSourceGroup* pSrcGrp;
	IWMEncSource* pAudSrc;
	IWMEncSource* pVidSrc;
	IWMEncProfileCollection* pProColl;
	IWMEncProfile* pPro;
	IWMEncFile* pFile;
	long lCount;
	int i;


	// Initialize the COM library and retrieve a pointer
	// to an IWMEncoder interface.

	hr = CoInitialize(NULL);
	if (SUCCEEDED(hr))
	{
		hr = CoCreateInstance(CLSID_WMEncoder,
			NULL,
			CLSCTX_INPROC_SERVER,
			IID_IWMEncoder,
			(void**)&pEncoder);
	}

	// Retrieve a pointer to an IWMEncSourceGroupCollection
	// interface.

	if (SUCCEEDED(hr))
	{
		hr = pEncoder->get_SourceGroupCollection(&pSrcGrpColl);
	}

	// Add an empty source group to the collection.

	if (SUCCEEDED(hr))
	{
		hr = pSrcGrpColl->Add(CComBSTR("SG_1"), &pSrcGrp);
	}

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

	if (SUCCEEDED(hr))
	{
		hr = pSrcGrp->AddSource(WMENC_AUDIO, &pAudSrc);
	}
	if (SUCCEEDED(hr))
	{
		hr = pSrcGrp->AddSource(WMENC_VIDEO, &pVidSrc);
	}

	// Retrieve a pointer to an IWMEncFile interface.

	if (SUCCEEDED(hr))
	{
		hr = pEncoder->get_File(&pFile);
	}

	// Specify an .avi source file and a Windows Media file with a .wmv extension for the output.

	CComBSTR m_bstrInFile("C:\\input.avi");
	CComBSTR m_bstrOutFile("C:\\output.wmv");

	if (SUCCEEDED(hr))
	{
		hr = pAudSrc->SetInput(m_bstrInFile);
	}
	if (SUCCEEDED(hr))
	{
		hr = pVidSrc->SetInput(m_bstrInFile);
	}
	if (SUCCEEDED(hr))
	{
		hr = pFile->put_LocalFileName(m_bstrOutFile);
	}

	// Retrieve the name of the output file.

	CComBSTR m_bstrFileName(" ");
	if (SUCCEEDED(hr))
	{
		hr = pFile->get_LocalFileName(&m_bstrFileName);
	}

	// Loop through the profile collection and retrieve a specific
	// profile. You can find the profile name in the Profile Manager.

	if (SUCCEEDED(hr))
	{
		hr = pEncoder->get_ProfileCollection(&pProColl);
	}
	CComBSTR m_bstrName(" ");
	CComVariant m_varProfile;
	m_varProfile.vt = VT_DISPATCH;
	if (SUCCEEDED(hr))
	{
		hr = pProColl->get_Count(&lCount);
	}
	for (i = 0; i < lCount; i++)
	{
		if (SUCCEEDED(hr))
		{
			hr = pProColl->Item(i, &pPro);
		}
		if (SUCCEEDED(hr))
		{
			hr = pPro->get_Name(&m_bstrName);
		}
		if (_wcsicmp(m_bstrName, CComBSTR("profile_name")) == 0)
		{
			m_varProfile.pdispVal = pPro;
			if (SUCCEEDED(hr))
			{
				hr = pSrcGrp->put_Profile(m_varProfile);
			}
			break;
		}
	}

	// Start archiving when the encoding process starts. This is the default.

	if (SUCCEEDED(hr))
	{
		hr = pEncoder->put_EnableAutoArchive(VARIANT_TRUE);
	}

	// Initialize and start the encoding process.

	if (SUCCEEDED(hr))
	{
		hr = pEncoder->PrepareToEncode(VARIANT_TRUE);
	}
	if (SUCCEEDED(hr))
	{
		hr = pEncoder->Start();
	}

	// To determine when the encoding and archiving process has ended,
	// you must implement the OnArchiveStateChange event in the
	// _IWMEncoderEvents interface.

	// Release pointers.
	if (pEncoder)
	{
		pEncoder->Release();
		pEncoder = NULL;
	}
	if (pSrcGrpColl)
	{
		pSrcGrpColl->Release();
		pSrcGrpColl = NULL;
	}
	if (pSrcGrp)
	{
		pSrcGrp->Release();
		pSrcGrp = NULL;
	}
	if (pAudSrc)
	{
		pAudSrc->Release();
		pAudSrc = NULL;
	}
	if (pVidSrc)
	{
		pVidSrc->Release();
		pVidSrc = NULL;
	}
	if (pProColl)
	{
		pProColl->Release();
		pProColl = NULL;
	}
	if (pPro)
	{
		pPro->Release();
		pPro = NULL;
	}
	if (pFile)
	{
		pFile->Release();
		pFile = NULL;
	}

}

編譯成功,然後運行調試,發現每次都獲取COM組件失敗,坑人吧,在網上搜了一通,猜測是安裝方式導致COM組件沒有註冊成功,具體怎麼才能在win10 上註冊成功,這個就沒有繼續調查,還是乖乖的在win7下搞,比較太久遠了。至此就完成了這個需求。

三、腳本調用

等等,好像他的需求只是轉格式文件而已, 幹嘛非要用c++寫程序呢,難道用腳本實現不香嗎?很明顯他的業務就是在服務器後端將格式轉化成WMV格式,然後供前端下載或播放,你就算寫個二次開發程序估計也是以腳本的形式調用,那就看看腳本功能支不支持,有沒有很強大,結果發現,腳本功能很強大,基本功能就無需這個二次開發插件,一句話就完成了轉化:

cscript.exe wmcmd.vbs –input C:\My-clips\Myfile.avi -output C:\My-clips-coded\Myfile.wmv

最後,我把命令行告訴了他,然後果然很香,以後再也不用二次開發了,直接用命令行就妥妥的,畢竟這種古老的格式,誰還會有那麼多需求呢。在ENCODER 安裝目錄下有幫助文檔對命令行進行詳細說明:

最後,下載資源參加下面的資源連接

https://download.csdn.net/download/liyuanba2dai/12314465

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章