Bagikan melalui


Menggunakan Sumber Pengurut

Topik ini menjelaskan cara menggunakan Sumber Sequencer. Hal ini berisi bagian-bagian berikut:

Untuk gambaran umum sumber pengurut, lihat Tentang Sumber Sequencer.

Gambaran Umum

Sumber pengurut mengekspos antarmuka berikut.

Antarmuka Deskripsi
IMFMediaSource Mengekspos fungsionalitas sumber media generik.
IMFSequencerSource Memungkinkan aplikasi untuk menambahkan atau menghapus topologi.
IMFMediaSourceTopologyProvider Mengambil topologi berikutnya untuk mengantre pada Sesi Media.
IMFMediaSourcePresentationProvider Digunakan oleh Sesi Media untuk mengakhiri segmen. Aplikasi tidak menggunakan antarmuka ini.
IMFGetService Mengkueri sumber pengurut untuk Antarmuka Layanan.

 

Untuk memutar urutan sumber media, lakukan langkah-langkah berikut:

  1. Untuk membuat sumber pengurut, panggil fungsi MFCreateSequencerSource.
  2. Untuk setiap segmen, buat topologi pemutaran, seperti yang dijelaskan dalam Membuat Topologi Pemutaran. Untuk menambahkan topologi ke presentasi, panggil IMFSequencerSource::AppendTopology.
  3. Sebelum memulai pemutaran, panggil IMFMediaSource::CreatePresentationDescriptor pada sumber pengurut. Metode ini mengembalikan penunjuk ke deskriptor presentasi untuk segmen pertama. Untuk mendapatkan topologi yang terkait dengan segmen ini, panggil QueryInterface pada sumber pengurut untuk antarmuka IMFMediaSourceTopologyProvider. Teruskan deskriptor presentasi ke metode IMFMediaSourceTopologyProvider::GetMediaSourceTopology. Metode ini mengembalikan penunjuk ke topologi.
  4. Teruskan topologi untuk segmen pertama ke Sesi Media, dengan memanggil metode IMFMediaSession::SetTopology Sesi Media.
  5. Mulai pemutaran dengan memanggil IMFMediaSession::Start.
  6. Ketika sumber pengurut siap untuk mendaftarkan segmen berikutnya, sumber tersebut mengirimkan peristiwa MENewPresentation yang data peristiwanya adalah penunjuk antarmuka IMFPresentationDescriptor. Sekali lagi, dapatkan topologi untuk segmen dengan memanggil GetMediaSourceTopology pada sumber pengurut, dan atur topologi pada Sesi Media dengan memanggil SetTopology. Tidak perlu memulai kembali sumber media; secara otomatis akan diputar ke segmen berikutnya.
  7. Sebelum aplikasi berhenti, matikan sumber pengurut dengan memanggil IMFMediaSource::Shutdown.

Kode berikut menunjukkan cara mendapatkan topologi dan mengaturnya pada Sesi Media:

// Queues the next topology on the session.

HRESULT CPlaylist::QueueNextSegment(IMFPresentationDescriptor *pPD)
{
    IMFMediaSourceTopologyProvider *pTopoProvider = NULL;
    IMFTopology *pTopology = NULL;

    //Get the topology for the presentation descriptor
    HRESULT hr = m_pSequencerSource->QueryInterface(IID_PPV_ARGS(&pTopoProvider));
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pTopoProvider->GetMediaSourceTopology(pPD, &pTopology);
    if (FAILED(hr))
    {
        goto done;
    }

    //Set the topology on the media session
    m_pSession->SetTopology(NULL, pTopology);

done:
    SafeRelease(&pTopoProvider);
    SafeRelease(&pTopology);
    return hr;
}

Untuk contoh kode lengkap, lihat Kode Contoh Sumber Sequencer.

Menambahkan Topologi

Sumber pengurut mempertahankan dua daftar topologi: daftar input dan daftar pra-pendaftaran.

Daftar input adalah kumpulan topologi yang sesuai dengan segmen daftar putar, dalam urutan ditambahkan oleh aplikasi dengan memanggil IMFSequencerSource::AppendTopology. Metode ini menetapkan setiap topologi pengidentifikasi segmen unik dari jenis MFSequencerElementId. Pengidentifikasi segmen diatur sebagai atribut untuk semua simpul topologi sumber. Aplikasi bisa mendapatkan pengidentifikasi segmen dari simpul sumber dengan menggunakan atribut MF_TOPONODE_SEQUENCE_ELEMENTID . Daftar input dapat memiliki topologi duplikat jika aplikasi yang disebut AppendTopology pada topologi yang sama lebih dari sekali; namun, mereka diidentifikasi oleh pengidentifikasi segmen unik mereka.

Daftar pra-pendaftaran adalah kumpulan topologi daftar input yang telah diinisialisasi sebagai persiapan untuk pemutaran. Ini memungkinkan Sesi Media untuk beralih ke topologi berikutnya dengan mulus ketika topologi aktif berakhir. Aplikasi tidak dapat langsung menambahkan atau menghapus topologi dari daftar pra-pendaftaran; ini dihasilkan oleh sumber pengurut ketika topologi dari daftar input dipilih untuk pemutaran. Ini menyebabkan sumber pengurut menambahkan topologi berikutnya dari daftar input ke daftar pra-pendaftaran. Setelah melakukannya, sumber pengurut secara asinkron meningkatkan peristiwa MENewPresentation dan meneruskan deskriptor presentasi untuk topologi pra-pendaftaran sebagai data peristiwa. Aplikasi harus mendengarkan peristiwa ini dengan menggunakan antarmuka IMFMediaEventGenerator Sesi Media dan mengantrekan topologi pra-pendaftaran pada Sesi Media dengan memanggil IMFMediaSession::SetTopology. Ini harus dilakukan sebelum Sesi Media menyelesaikan pemutaran topologi aktif. SetTopology menginformasikan Sesi Media tentang topologi berikutnya yang harus diputar setelah pemutaran topologi aktif berakhir. Untuk memastikan transisi yang mulus, aplikasi harus memanggil SetTopology sebelum Sesi Media selesai memutar topologi sebelumnya. Jika tidak, akan ada kesenjangan antara segmen.

Acara MENewPresentation dimunculkan selama ada topologi setelah topologi aktif. Akibatnya, jika daftar input hanya berisi satu topologi, atau jika topologi aktif adalah yang terakhir dalam daftar input, peristiwa ini tidak dimunculkan.

Daftar pra-pendaftaran disinkronkan dengan daftar input dan di-refresh setiap kali topologi ditambahkan ke atau dihapus dari daftar input.

Menghapus Topologi

Untuk menghapus topologi dari sumber pengurut, aplikasi harus memanggil metode IMFSequencerSource::D eleteTopology dan menentukan pengidentifikasi segmen.

Sebelum memanggil DeleteTopology, aplikasi harus memastikan bahwa Sesi Media tidak menggunakan topologi yang ingin dihapus aplikasi. Untuk melakukan ini, kedua hal berikut harus terjadi sebelum aplikasi memanggil DeleteTopology:

  • Acara MESessionTopologyStatus dengan MF_TOPOSTATUS_ENDED diterima untuk topologi untuk memastikan bahwa Sesi Media telah menyelesaikan pemutaran.

  • MESessionTopologyStatus dengan MF_TOPOSTATUS_STARTED_SOURCE diterima untuk topologi berikutnya untuk memastikan bahwa Sesi Media telah mulai memutar topologi berikutnya, peristiwa MESessionEnded diterima untuk memastikan bahwa Sesi Media dilakukan dengan topologi terakhir di sumber pengurut.

Jika segmen yang dihapus adalah topologi aktif, pemutaran dihentikan dan sumber pengurut meningkatkan peristiwa MEEndOfPresentationSegment . Jika topologi aktif juga merupakan topologi terakhir, peristiwa MEEndOfPresentation akan dinaikkan.

Melompat ke Segmen

Aplikasi dapat melompat ke segmen tertentu dalam urutan dengan memulai Sesi Media dengan offset segmen, sebagai berikut:

  1. Panggil fungsi MFCreateSequencerSegmentOffset untuk membuat offset segmen. Tentukan pengidentifikasi segmen dalam parameter dwId . (Pengidentifikasi dikembalikan oleh Metode IMFSequencerSource::AppendTopology ketika Anda pertama kali menambahkan topologi ke sumber pengurut.) Parameter hnsOffset menentukan offset waktu, relatif terhadap awal segmen. Pemutaran akan dimulai saat ini. Untuk parameter pvarSegmentOffset, berikan alamat PROPVARIANT kosong. Saat fungsi kembali, PROPVARIANT ini berisi offset segmen.

  2. Panggil metode IMFMediaSession::Start pada Sesi Media. Untuk parameter pguidTimeFormat, gunakan nilai GUID MF_TIME_FORMAT_SEGMENT_OFFSET. Nilai ini menunjukkan pencarian berdasarkan offset segmen. Untuk parameter pvarStartPosition, berikan alamat PROPVARIANT yang dibuat pada langkah sebelumnya.

Contoh kode berikut menunjukkan cara melompat ke awal segmen tertentu secara berurutan.

// Skips to the specified segment in the sequencer source

HRESULT CPlaylist::SkipTo(DWORD index)
{
    if (index >= m_count)
    {
        return E_INVALIDARG;
    }

    MFSequencerElementId ID = m_segments[index].SegmentID;

    PROPVARIANT var;

    HRESULT hr = MFCreateSequencerSegmentOffset(ID, NULL, &var);
    
    if (SUCCEEDED(hr))
    {
        hr = m_pSession->Start(&MF_TIME_FORMAT_SEGMENT_OFFSET, &var);
        PropVariantClear(&var);
    }
    return hr;
}

Ketika aplikasi mencari di seluruh segmen, aplikasi menerima beberapa peristiwa karena sumber pengurut mengakhiri segmen saat ini dan bersiap untuk memutar segmen baru. Karena peristiwa ini diterima secara asinkron, sulit untuk memprediksi urutan peristiwa yang tepat. Peristiwa-peristiwa ini adalah sebagai berikut:

Detail selengkapnya tentang peristiwa yang dikirim oleh sumber pengurut dapat ditemukan dalam topik Peristiwa Sumber Pengurut.

Cara Membuat Daftar Putar

Sumber Pengurut