Commit dd61c758 authored by Cyril Mathé's avatar Cyril Mathé Committed by Jean-Baptiste Kempf

ActiveX: Improve subtitle and audio track JS bindings

- audio.count: give the number of available audio track
  - audio.description(int n): give the name of the n-th audio track
  - subtitle.count: give the number of available subtitle track
  - subtitle.description(int n): give the name of the n-th subtitle track
  - subtitle.track: get and set the subtitle track to show (similar as video.subtitle)
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent be4893df
......@@ -42,6 +42,7 @@ library AXVLC
interface IVLCMessageIterator;
interface IVLCMessages;
interface IVLCPlaylist;
interface IVLCSubtitle;
interface IVLCVideo;
interface IVLCControl2;
dispinterface DVLCEvents;
......@@ -208,6 +209,11 @@ library AXVLC
[propput, helpstring("Returns/sets audio track used/to use.")]
HRESULT track([in] long track);
[propget, helpstring("Returns the number of audio tracks available.")]
HRESULT count([out, retval] long* trackNumber);
[helpstring("Returns audio track name.")]
HRESULT description([in] long trackID, [out, retval] BSTR* name);
[propget, helpstring("Returns audio channel [1-5] indicating; stereo, reverse stereo, left, right, dolby.")]
HRESULT channel([out, retval] long* channel);
[propput, helpstring("Sets audio channel to [1-5] indicating; stereo, reverse stereo, left, right, dolby.")]
......@@ -400,6 +406,26 @@ library AXVLC
HRESULT items([out, retval] IVLCPlaylistItems** obj);
};
[
odl,
uuid(465E787A-0556-452F-9477-954E4A940003),
helpstring("VLC Subtitle APIs"),
dual,
oleautomation
]
interface IVLCSubtitle : IDispatch
{
[propget, helpstring("Returns video subtitle used.")]
HRESULT track([out, retval] long* spu);
[propput, helpstring("Sets video subtitle to use.")]
HRESULT track([in] long spu);
[propget, helpstring("Returns the number of video subtitles available.")]
HRESULT count([out, retval] long* spuNumber);
[helpstring("Returns video subtitle name.")]
HRESULT description([in] long nameID, [out, retval] BSTR* name);
};
[
odl,
uuid(0AAEDF0B-D333-4B27-A0C6-BBF31413A42E),
......@@ -525,6 +551,9 @@ library AXVLC
[propget, helpstring("Returns the playlist object.")]
HRESULT playlist([out, retval] IVLCPlaylist** obj);
[propget, helpstring("Returns the audio object.")]
HRESULT subtitle([out, retval] IVLCSubtitle** obj);
[propget, helpstring("Returns the audio object.")]
HRESULT video([out, retval] IVLCVideo** obj);
};
......
......@@ -238,6 +238,90 @@ STDMETHODIMP VLCAudio::put_track(long track)
return hr;
};
STDMETHODIMP VLCAudio::get_count(long* trackNumber)
{
if( NULL == trackNumber )
return E_POINTER;
libvlc_media_player_t* p_md;
HRESULT hr = _p_instance->getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_exception_t ex;
libvlc_exception_init(&ex);
// get the number of audio track available and return it
*trackNumber = libvlc_audio_get_track_count(p_md, &ex);
if( libvlc_exception_raised(&ex) )
{
_p_instance->setErrorInfo(IID_IVLCAudio,
libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
return NOERROR;
}
return hr;
};
STDMETHODIMP VLCAudio::description(long trackID, BSTR* name)
{
if( NULL == name )
return E_POINTER;
libvlc_media_player_t* p_md;
libvlc_exception_t ex;
libvlc_exception_init(&ex);
HRESULT hr = _p_instance->getMD(&p_md);
if( SUCCEEDED(hr) )
{
int i, i_limit;
const char *psz_name;
libvlc_track_description_t *p_trackDesc;
// get tracks description
p_trackDesc = libvlc_audio_get_track_description(p_md, &ex);
if( libvlc_exception_raised(&ex) )
{
_p_instance->setErrorInfo(IID_IVLCAudio, libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
//get the number of available track
i_limit = libvlc_audio_get_track_count(p_md, &ex);
if( libvlc_exception_raised(&ex) )
{
_p_instance->setErrorInfo(IID_IVLCAudio, libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
// check if the number given is a good one
if ( ( trackID > ( i_limit -1 ) ) || ( trackID < 0 ) )
return E_FAIL;
// get the good trackDesc
for( i = 0 ; i < trackID ; i++ )
{
p_trackDesc = p_trackDesc->p_next;
}
// get the track name
psz_name = p_trackDesc->psz_name;
// return it
if( psz_name != NULL )
{
*name = BSTRFromCStr(CP_UTF8, psz_name);
return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
}
*name = NULL;
return E_FAIL;
}
return hr;
};
STDMETHODIMP VLCAudio::get_channel(long *channel)
{
if( NULL == channel )
......@@ -1645,6 +1729,213 @@ STDMETHODIMP VLCPlaylist::get_items(IVLCPlaylistItems** obj)
/*******************************************************************************/
VLCSubtitle::~VLCSubtitle()
{
if( _p_typeinfo )
_p_typeinfo->Release();
};
HRESULT VLCSubtitle::loadTypeInfo(void)
{
HRESULT hr = NOERROR;
if( NULL == _p_typeinfo )
{
ITypeLib *p_typelib;
hr = _p_instance->getTypeLib(LOCALE_USER_DEFAULT, &p_typelib);
if( SUCCEEDED(hr) )
{
hr = p_typelib->GetTypeInfoOfGuid(IID_IVLCSubtitle, &_p_typeinfo);
if( FAILED(hr) )
{
_p_typeinfo = NULL;
}
p_typelib->Release();
}
}
return hr;
};
STDMETHODIMP VLCSubtitle::GetTypeInfoCount(UINT* pctInfo)
{
if( NULL == pctInfo )
return E_INVALIDARG;
if( SUCCEEDED(loadTypeInfo()) )
*pctInfo = 1;
else
*pctInfo = 0;
return NOERROR;
};
STDMETHODIMP VLCSubtitle::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
{
if( NULL == ppTInfo )
return E_INVALIDARG;
if( SUCCEEDED(loadTypeInfo()) )
{
_p_typeinfo->AddRef();
*ppTInfo = _p_typeinfo;
return NOERROR;
}
*ppTInfo = NULL;
return E_NOTIMPL;
};
STDMETHODIMP VLCSubtitle::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames,
UINT cNames, LCID lcid, DISPID* rgDispID)
{
if( SUCCEEDED(loadTypeInfo()) )
{
return DispGetIDsOfNames(_p_typeinfo, rgszNames, cNames, rgDispID);
}
return E_NOTIMPL;
};
STDMETHODIMP VLCSubtitle::Invoke(DISPID dispIdMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
if( SUCCEEDED(loadTypeInfo()) )
{
return DispInvoke(this, _p_typeinfo, dispIdMember, wFlags, pDispParams,
pVarResult, pExcepInfo, puArgErr);
}
return E_NOTIMPL;
};
STDMETHODIMP VLCSubtitle::get_track(long* spu)
{
if( NULL == spu )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = _p_instance->getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_exception_t ex;
libvlc_exception_init(&ex);
*spu = libvlc_video_get_spu(p_md, &ex);
if( ! libvlc_exception_raised(&ex) )
{
return NOERROR;
}
_p_instance->setErrorInfo(IID_IVLCSubtitle, libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
return hr;
};
STDMETHODIMP VLCSubtitle::put_track(long spu)
{
libvlc_media_player_t *p_md;
HRESULT hr = _p_instance->getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_exception_t ex;
libvlc_exception_init(&ex);
libvlc_video_set_spu(p_md, spu, &ex);
if( libvlc_exception_raised(&ex) )
{
_p_instance->setErrorInfo(IID_IVLCSubtitle, libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
return NOERROR;
}
return hr;
};
STDMETHODIMP VLCSubtitle::get_count(long* spuNumber)
{
if( NULL == spuNumber )
return E_POINTER;
libvlc_media_player_t *p_md;
HRESULT hr = _p_instance->getMD(&p_md);
if( SUCCEEDED(hr) )
{
libvlc_exception_t ex;
libvlc_exception_init(&ex);
// get the number of video subtitle available and return it
*spuNumber = libvlc_video_get_spu_count(p_md, &ex);
if( libvlc_exception_raised(&ex) )
{
_p_instance->setErrorInfo(IID_IVLCSubtitle, libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
return NOERROR;
}
return hr;
};
STDMETHODIMP VLCSubtitle::description(long nameID, BSTR* name)
{
if( NULL == name )
return E_POINTER;
libvlc_media_player_t* p_md;
libvlc_exception_t ex;
libvlc_exception_init(&ex);
HRESULT hr = _p_instance->getMD(&p_md);
if( SUCCEEDED(hr) )
{
int i, i_limit;
const char *psz_name;
libvlc_track_description_t *p_spuDesc;
// get subtitles description
p_spuDesc = libvlc_video_get_spu_description(p_md, &ex);
if( libvlc_exception_raised(&ex) )
{
_p_instance->setErrorInfo(IID_IVLCSubtitle, libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
// get the number of available subtitle
i_limit = libvlc_video_get_spu_count(p_md, &ex);
if( libvlc_exception_raised(&ex) )
{
_p_instance->setErrorInfo(IID_IVLCSubtitle, libvlc_exception_get_message(&ex));
libvlc_exception_clear(&ex);
return E_FAIL;
}
// check if the number given is a good one
if ( ( nameID > ( i_limit -1 ) ) || ( nameID < 0 ) )
return E_FAIL;
// get the good spuDesc
for( i = 0 ; i < nameID ; i++ )
{
p_spuDesc = p_spuDesc->p_next;
}
// get the subtitle name
psz_name = p_spuDesc->psz_name;
// return it
if( psz_name != NULL )
{
*name = BSTRFromCStr(CP_UTF8, psz_name);
return (NULL == *name) ? E_OUTOFMEMORY : NOERROR;
}
*name = NULL;
return E_FAIL;
}
return hr;
};
/*******************************************************************************/
VLCVideo::~VLCVideo()
{
if( _p_typeinfo )
......@@ -2104,18 +2395,21 @@ VLCControl2::VLCControl2(VLCPlugin *p_instance) :
_p_vlcaudio(NULL),
_p_vlcinput(NULL),
_p_vlcplaylist(NULL),
_p_vlcsubtitle(NULL),
_p_vlcvideo(NULL)
{
_p_vlcaudio = new VLCAudio(p_instance);
_p_vlcinput = new VLCInput(p_instance);
_p_vlclog = new VLCLog(p_instance);
_p_vlcplaylist = new VLCPlaylist(p_instance);
_p_vlcsubtitle = new VLCSubtitle(p_instance);
_p_vlcvideo = new VLCVideo(p_instance);
};
VLCControl2::~VLCControl2()
{
delete _p_vlcvideo;
delete _p_vlcsubtitle;
delete _p_vlcplaylist;
delete _p_vlclog;
delete _p_vlcinput;
......@@ -2427,6 +2721,20 @@ STDMETHODIMP VLCControl2::get_playlist(IVLCPlaylist** obj)
return E_OUTOFMEMORY;
};
STDMETHODIMP VLCControl2::get_subtitle(IVLCSubtitle** obj)
{
if( NULL == obj )
return E_POINTER;
*obj = _p_vlcsubtitle;
if( NULL != _p_vlcsubtitle )
{
_p_vlcsubtitle->AddRef();
return NOERROR;
}
return E_OUTOFMEMORY;
};
STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
{
if( NULL == obj )
......
......@@ -68,9 +68,11 @@ public:
STDMETHODIMP put_volume(long);
STDMETHODIMP get_track(long*);
STDMETHODIMP put_track(long);
STDMETHODIMP get_count(long*);
STDMETHODIMP get_channel(long*);
STDMETHODIMP put_channel(long);
STDMETHODIMP toggleMute();
STDMETHODIMP description(long, BSTR*);
protected:
HRESULT loadTypeInfo();
......@@ -489,6 +491,54 @@ private:
VLCPlaylistItems* _p_vlcplaylistitems;
};
class VLCSubtitle : public IVLCSubtitle
{
public:
VLCSubtitle(VLCPlugin *p_instance) :
_p_instance(p_instance), _p_typeinfo(NULL) {};
virtual ~VLCSubtitle();
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( NULL == ppv )
return E_POINTER;
if( (IID_IUnknown == riid)
|| (IID_IDispatch == riid)
|| (IID_IVLCSubtitle == riid) )
{
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
// behaves as a standalone object
return E_NOINTERFACE;
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IDispatch methods
STDMETHODIMP GetTypeInfoCount(UINT*);
STDMETHODIMP GetTypeInfo(UINT, LCID, LPTYPEINFO*);
STDMETHODIMP GetIDsOfNames(REFIID,LPOLESTR*,UINT,LCID,DISPID*);
STDMETHODIMP Invoke(DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
// IVLCSubtitle methods
STDMETHODIMP get_track(long*);
STDMETHODIMP put_track(long);
STDMETHODIMP get_count(long*);
STDMETHODIMP description(long, BSTR*);
protected:
HRESULT loadTypeInfo();
private:
VLCPlugin* _p_instance;
ITypeInfo* _p_typeinfo;
};
class VLCVideo : public IVLCVideo
{
public:
......@@ -606,6 +656,7 @@ public:
STDMETHODIMP get_input(IVLCInput**);
STDMETHODIMP get_log(IVLCLog**);
STDMETHODIMP get_playlist(IVLCPlaylist**);
STDMETHODIMP get_subtitle(IVLCSubtitle**);
STDMETHODIMP get_video(IVLCVideo**);
protected:
......@@ -619,6 +670,7 @@ private:
VLCInput* _p_vlcinput;
VLCLog * _p_vlclog;
VLCPlaylist* _p_vlcplaylist;
VLCSubtitle* _p_vlcsubtitle;
VLCVideo* _p_vlcvideo;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment