Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule pokazano, jak używać interfejsu IMediaEncodingProperties w celu ustawienia rozdzielczości i szybkości klatek strumienia podglądu aparatu oraz przechwyconych zdjęć i wideo. Pokazuje również, jak upewnić się, że współczynnik proporcji strumienia podglądu jest zgodny z współczynnikiem proporcji przechwyconego nośnika.
Profile kamer oferują prostszy, wyższy mechanizm wykrywania i ustawiania właściwości strumienia aparatu, ale nie są obsługiwane dla wszystkich urządzeń. Aby uzyskać więcej informacji, zobacz Profile aparatów fotograficznych.
Określ, czy strumienie podglądu i przechwytywania są niezależne
Na niektórych urządzeniach ten sam pin sprzętowy jest używany zarówno do strumieni w wersji zapoznawczej, jak i przechwytywania. Na tych urządzeniach ustawienie właściwości kodowania, takich jak format, rozdzielczość i szybkość klatek na jednym, będzie miało wpływ na obie te wartości. Na urządzeniach, które używają różnych pinów sprzętowych do przechwytywania i podglądu, właściwości można ustawić niezależnie dla każdego strumienia. Użyj poniższego kodu, aby określić, czy strumienie podglądu i przechwytywania są niezależne. W tym przykładzie ustawiono globalną zmienną boolowską, która może służyć do zmiany zachowania aplikacji, jeśli strumienie są współużytkowane lub niezależne.
if (m_mediaCapture.MediaCaptureSettings.VideoDeviceCharacteristic == VideoDeviceCharacteristic.AllStreamsIdentical ||
m_mediaCapture.MediaCaptureSettings.VideoDeviceCharacteristic == VideoDeviceCharacteristic.PreviewRecordStreamsIdentical)
{
m_captureAndPreviewStreamsIdentical = true;
}
Klasa pomocnika właściwości kodowania multimediów
Utworzenie prostej klasy pomocniczej w celu opakowania funkcjonalności interfejsu IMediaEncodingProperties ułatwia wybranie zestawu właściwości kodowania spełniających określone kryteria. Ta klasa pomocnicza jest szczególnie przydatna ze względu na następujące zachowanie funkcji właściwości enkodowania:
Uwaga / Notatka
Metoda VideoDeviceController.GetAvailableMediaStreamProperties przyjmuje element członkowski wyliczenia MediaStreamType, na przykład: VideoRecord lub Photo, i zwraca listę obiektów ImageEncodingProperties lub VideoEncodingProperties, które przekazują ustawienia kodowania strumienia, takie jak rozdzielczość przechwyconego zdjęcia lub wideo. Wyniki wywoływania metody GetAvailableMediaStreamProperties mogą obejmować właściwości ImageEncodingProperties lub VideoEncodingProperties niezależnie od określonej wartości MediaStreamType . Z tego powodu należy zawsze sprawdzać typ każdej zwróconej wartości i rzutować ją do odpowiedniego typu przed próbą uzyskania dostępu do dowolnych wartości właściwości.
Klasa pomocnicza zdefiniowana poniżej obsługuje sprawdzanie typów i rzutowanie dla ImageEncodingProperties lub VideoEncodingProperties, dzięki czemu kod Twojej aplikacji nie musi rozróżniać między tymi dwoma typami. Oprócz tego klasa pomocnika uwidacznia właściwości współczynnika proporcji, szybkość klatek (tylko dla właściwości kodowania wideo) i czytelną nazwę, która ułatwia wyświetlanie właściwości kodowania w UI.
class StreamPropertiesHelper
{
private IMediaEncodingProperties _properties;
public StreamPropertiesHelper(IMediaEncodingProperties properties)
{
if (properties == null)
{
throw new ArgumentNullException(nameof(properties));
}
// This helper class only uses ImageEncodingProperties or VideoEncodingProperties
if (!(properties is ImageEncodingProperties) && !(properties is VideoEncodingProperties))
{
throw new ArgumentException("Argument is of the wrong type. Required: " + typeof(ImageEncodingProperties).Name
+ " or " + typeof(VideoEncodingProperties).Name + ".", nameof(properties));
}
// Store the actual instance of the IMediaEncodingProperties for setting them later
_properties = properties;
}
public uint Width
{
get
{
if (_properties is ImageEncodingProperties)
{
return (_properties as ImageEncodingProperties).Width;
}
else if (_properties is VideoEncodingProperties)
{
return (_properties as VideoEncodingProperties).Width;
}
return 0;
}
}
public uint Height
{
get
{
if (_properties is ImageEncodingProperties)
{
return (_properties as ImageEncodingProperties).Height;
}
else if (_properties is VideoEncodingProperties)
{
return (_properties as VideoEncodingProperties).Height;
}
return 0;
}
}
public uint FrameRate
{
get
{
if (_properties is VideoEncodingProperties)
{
if ((_properties as VideoEncodingProperties).FrameRate.Denominator != 0)
{
return (_properties as VideoEncodingProperties).FrameRate.Numerator /
(_properties as VideoEncodingProperties).FrameRate.Denominator;
}
}
return 0;
}
}
public double AspectRatio
{
get { return Math.Round((Height != 0) ? (Width / (double)Height) : double.NaN, 2); }
}
public IMediaEncodingProperties EncodingProperties
{
get { return _properties; }
}
public string GetFriendlyName(bool showFrameRate = true)
{
if (_properties is ImageEncodingProperties ||
!showFrameRate)
{
return Width + "x" + Height + " [" + AspectRatio + "] " + _properties.Subtype;
}
else if (_properties is VideoEncodingProperties)
{
return Width + "x" + Height + " [" + AspectRatio + "] " + FrameRate + "FPS " + _properties.Subtype;
}
return String.Empty;
}
}
Pobieranie listy dostępnych właściwości strumienia
Pobierz listę dostępnych właściwości strumienia dla urządzenia przechwytywania, uzyskując element VideoDeviceController dla obiektu MediaCapture aplikacji, a następnie wywołując metodę GetAvailableMediaStreamProperties i przekazując jedną z wartości MediaStreamType , VideoPreview, VideoRecord lub Photo. W tym przykładzie zostanie utworzona lista obiektów StreamPropertiesHelper zdefiniowanych wcześniej w tym artykule dla każdego z wartości IMediaEncodingProperties zwróconych z właściwości GetAvailableMediaStreamProperties. W tym przykładzie zwracane właściwości są porządkowane najpierw na podstawie rozdzielczości, a następnie szybkości klatek.
Jeśli aplikacja ma określone wymagania dotyczące rozdzielczości lub szybkości klatek, możesz programowo wybrać zestaw właściwości kodowania multimediów. Typowa aplikacja aparatu zamiast tego uwidacznia listę dostępnych właściwości w interfejsie użytkownika i umożliwia użytkownikowi wybranie żądanych ustawień. ComboBoxItem jest tworzony dla każdego elementu na liście obiektów StreamPropertiesHelper w liście. Zawartość jest ustawiona na przyjazną nazwę zwracaną przez klasę pomocnika, a tag jest ustawiony na samą klasę pomocnika, aby można było jej później użyć do pobrania skojarzonych właściwości kodowania. Każdy element ComboBoxItem jest następnie dodawany do pola ComboBox zdefiniowanego w interfejsie użytkownika.
private void bGetStreamProperties_Click(object sender, RoutedEventArgs e)
{
// Query all properties of the specified stream type
IEnumerable<StreamPropertiesHelper> allStreamProperties =
m_mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.VideoRecord).Select(x => new StreamPropertiesHelper(x));
// Order them by resolution then frame rate
allStreamProperties = allStreamProperties.OrderByDescending(x => x.Height * x.Width).ThenByDescending(x => x.FrameRate);
// Populate the combo box with the entries
foreach (var property in allStreamProperties)
{
ComboBoxItem comboBoxItem = new ComboBoxItem();
comboBoxItem.Content = property.GetFriendlyName();
comboBoxItem.Tag = property;
cbStreamProperties.Items.Add(comboBoxItem);
}
}
Ustawianie żądanych właściwości strumienia
Poinformuj kontroler urządzenia wideo, aby używał żądanych właściwości kodowania, wywołując metodę SetMediaStreamPropertiesAsync, przekazując wartość MediaStreamType wskazującą, czy należy ustawić właściwości zdjęcia, wideo lub podglądu. W tym przykładzie użyto pola ComboBox wypełnionego w przykładzie z poprzedniej sekcji, gdzie właściwości strumienia multimediów są pobierane z właściwości tagu z wybranego elementu.
private async void bSetStreamProperties_Click(object sender, RoutedEventArgs e)
{
if (m_exclusiveCameraAccess)
{
var selectedItem = cbStreamProperties.SelectedItem as ComboBoxItem;
var encodingProperties = (selectedItem.Tag as StreamPropertiesHelper).EncodingProperties;
await m_mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, encodingProperties);
}
}
Pamiętaj, że aplikacja musi mieć wyłączną kontrolę nad urządzeniem przechwytywania, aby zmienić właściwości strumienia multimediów.
Dopasuj proporcje strumieni podglądu i przechwytywania
Typowa aplikacja aparatu udostępnia interfejs użytkownika do wybierania rozdzielczości przechwytywania wideo lub zdjęć, ale programowo ustawi rozdzielczość podglądu. Istnieje kilka różnych strategii wybierania najlepszej rozdzielczości strumienia w wersji zapoznawczej dla aplikacji:
Wybierz najwyższą dostępną rozdzielczość w wersji zapoznawczej, aby platforma interfejsu użytkownika wykonywała wszelkie niezbędne skalowanie wersji zapoznawczej.
Wybierz rozdzielczość podglądu znajdującą się najbliżej rozdzielczości przechwytywania, aby podgląd wyświetlał najbliższą reprezentację końcowego przechwyconego nośnika.
Wybierz rozdzielczość podglądu znajdującą się najbliżej rozmiaru elementu CaptureElement , aby nie więcej pikseli niż to konieczne przechodziło przez potok strumienia podglądu.
Uwaga / Notatka
Na niektórych urządzeniach można ustawić inny współczynnik proporcji dla strumienia podglądu i strumienia przechwytywania aparatu. Kadrowanie spowodowane tą niezgodnością może prowadzić do tego, że w przechwyconym materiale pojawia się zawartość, która nie była widoczna w podglądzie, co może negatywnie wpłynąć na wrażenia użytkownika. Zdecydowanie zaleca się użycie tego samego współczynnika proporcji w niewielkim zakresie tolerancji dla strumieni podglądu i przechwytywania. W porządku jest włączać zupełnie inne rozdzielczości dla przechwytywania i wyświetlania podglądu, o ile współczynnik proporcji jest zbliżony.
Aby upewnić się, że strumienie przechwytywania zdjęć lub wideo są zgodne ze współczynnikiem proporcji strumienia podglądu, ten przykład wywołuje metodę VideoDeviceController.GetMediaStreamProperties i przekazuje wartość wyliczenia VideoPreview, aby uzyskać bieżące właściwości strumienia podglądu. Następnie definiujemy małe okno tolerancji współczynnika proporcji, aby uwzględnić współczynniki proporcji, które nie są dokładnie takie same jak strumień podglądu, o ile są do niego zbliżone. Następnie wybrano obiekty StreamPropertiesHelper , w których współczynnik proporcji mieści się w zdefiniowanym zakresie tolerancji strumienia podglądu.
// Query all properties of the specified stream type
IEnumerable<StreamPropertiesHelper> allVideoProperties =
m_mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.VideoRecord).Select(x => new StreamPropertiesHelper(x));
// Query the current preview settings
StreamPropertiesHelper previewProperties = new StreamPropertiesHelper(m_mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview));
// Get all formats that have the same-ish aspect ratio as the preview
// Allow for some tolerance in the aspect ratio comparison
const double ASPECT_RATIO_TOLERANCE = 0.015;
var matchingFormats = allVideoProperties.Where(x => Math.Abs(x.AspectRatio - previewProperties.AspectRatio) < ASPECT_RATIO_TOLERANCE);
// Order them by resolution then frame rate
allVideoProperties = matchingFormats.OrderByDescending(x => x.Height * x.Width).ThenByDescending(x => x.FrameRate);
// Clear out old entries and populate the video combo box with new matching entries
cbStreamProperties.Items.Clear();
foreach (var property in allVideoProperties)
{
ComboBoxItem comboBoxItem = new ComboBoxItem();
comboBoxItem.Content = property.GetFriendlyName();
comboBoxItem.Tag = property;
cbStreamProperties.Items.Add(comboBoxItem);
}
Fragment koduMatchPreviewAspectRatio