How to add scriptcommand/markers to live mms stream for sync


  • I am using Windows Media Server with Windows Media Encoder/Expression Encoder . I need to sync some activities with live stream in browser .Is there a way to do it serverside with Windows Media Service ?

    I know it can be done using Windows Media Encoder SDK but In my case end user is going to use Windows media encoder/Expression Encoder and I need to add timestamps to stream every 3 seconds . So its not possible to do it from user end . Can I create any Windows Media Service plugin or some other server side utility that can do it ?

    I am looking for some solutions for days now .... I hope some one can shed some light .

    venerdì 14 dicembre 2012 14:34


Tutte le risposte

  • WMS does not crack open the stream much beyond the header, so there is no way to do this server-side.  Instead you can use the Windows Media Format SDK,, to act as a mini-service that receives the stream from the encoder, modifies it, and then pushes it to WMS.
    lunedì 17 dicembre 2012 17:16
  • Thanks David !

    I have checked Windows Media Format SDK before and I couldn't find any pointers for live stream . Can you provide me some info on what methods I can use to achieve or any sample you could guide me to ?

    I have been working on some solution for more than a week so I would really appreciate your help .

    lunedì 17 dicembre 2012 17:23
  • If you install the Windows SDK one of the samples should be located in the C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\multimedia\windowsmediaformat\wmvnetwrite folder.  The WMVNetWrite sample will give the network interaction piece.  Beyond that I'd recommend reading through this:
    lunedì 17 dicembre 2012 17:50
  • Thanks that helped . Now I am listening to a publisher point get stream and publishing it to another publishing point . But while adding scriptcommand I get following error .

    " 0x8000FFFF" 

    HRESULT CNetWrite::OnStreamSample( WORD wStreamNum, 
                                      QWORD cnsSampleTime, 
                                      QWORD cnsSampleDuration, 
                                      DWORD dwFlags, 
                                      INSSBuffer __RPC_FAR *pSample, 
                                      void __RPC_FAR *pvContext )
        _tprintf( _T( "StreamSample: num=%d, time=%d, duration=%d, flags=%d.\n" ),
            wStreamNum, ( DWORD )cnsSampleTime, cnsSampleDuration, dwFlags );
        if( m_pWriterAdvanced != NULL )
            // Give the sample to the writer object.
            HRESULT hr = m_pWriterAdvanced->WriteStreamSample( wStreamNum,
                                                               pSample );
    		m_qwLastSampleTime = cnsSampleTime;
    		multimap<QWORD, ScriptCmd>::iterator i;
    		ScriptCmd Cmd;
    		Cmd.DataLen = 5;//(swprintf((WCHAR*)Cmd.Data, L"URL") + 1) * sizeof(WCHAR);
    		//Cmd.DataLen += (swprintf((WCHAR*)(Cmd.Data + Cmd.DataLen), L"%S", data.c_str()) + 1) * sizeof(WCHAR);
    		QWORD qwScriptTime = m_qwLastSampleTime + ((QWORD)5 * 10000I64);
    			m_Scripts.insert( make_pair(qwScriptTime, Cmd) );
    		_tprintf("Script Size :%d,Stream Num:%d", m_Scripts.size(),wStreamNum);
    		if (m_Scripts.size())
    			i = m_Scripts.begin();
    			while ((cnsSampleTime + 5000000I64) >= i->first)
    				// Pass sample to encoding engine in use.
    					INSSBuffer *pBuffer = NULL;
    					BYTE *lpOutputBuffer = NULL;
    					HRESULT hr = m_pWriter->AllocateSample(i->second.DataLen, &pBuffer);
    					if (FAILED(hr)){
    						_tprintf("ERROR: CNetWrite::OnStreamSample - Error 0x%X allocating sample from writer object.\n", hr);
    						throw hr;
    					hr = pBuffer->GetBuffer(&lpOutputBuffer);
    					if (FAILED(hr)){
    						_tprintf("ERROR: CNetWrite::OnStreamSample - Error 0x%X getting write buffer from buffer object.\n", hr);
    						throw hr;
    					CopyMemory(lpOutputBuffer, i->second.Data, i->second.DataLen);
    					hr = pBuffer->SetLength(i->second.DataLen);
    					if (FAILED(hr)){
    						_tprintf("ERROR: CNetWrite::OnStreamSample - Error 0x%X setting buffer length.\n", hr);
    						throw hr;
    					hr = m_pWriterAdvanced->WriteStreamSample( wStreamNum, i->first, 0, 0, dwFlags, pBuffer);
    					if (FAILED(hr)){
    						_tprintf("ERROR: CNetWrite::OnStreamSample - Error 0x%X writing script to stream.\n", hr);
    						throw hr;
    					WCHAR *pwszURL = wcschr((WCHAR*)i->second.Data, L'\0');
    					_tprintf("INFO: Successfully encoded script: %S at %I64d\n", pwszURL, i->first);
    					i = m_Scripts.begin();
    					if (m_Scripts.size() <= 0)
    		if( FAILED( hr ) )
                _tprintf( _T(  "Error 0x%x reported by the writer\n" ), hr );
                m_bEOF = true;
                m_hrAsync = hr;
                SetEvent( m_hEvent );
        return S_OK;

    mercoledì 19 dicembre 2012 18:42
  • Where do you get the error?
    venerdì 4 gennaio 2013 22:59