Compare commits

..

17 Commits

Author SHA1 Message Date
b34bce6e5f include id for homographyInfoGql 2024-11-08 17:25:54 -08:00
0e00ae9297 Merge pull request 'Add private to VideoGQL' (#125) from mk/not-clear into master
Reviewed-on: #125
2024-11-07 18:50:34 -07:00
e16812f242 ???
All checks were successful
Tests / Tests (pull_request) Successful in 16s
2024-11-07 17:49:36 -08:00
3e9b7a0d16 Merge pull request 'Add private field to user and videos' (#124) from mk/privacy into master
Reviewed-on: #124
2024-11-07 18:19:01 -07:00
309deb9473 Add private field to user and videos
All checks were successful
Tests / Tests (pull_request) Successful in 9s
2024-11-07 17:16:56 -08:00
d5ba9c2ba5 Merge pull request 'Remove id from HomographyInfo fragment for now, use string instead of base64 for FindPrerecordTableLayout' (#122) from loewy/switch-back-to-string into master
Reviewed-on: #122
2024-11-07 18:09:51 -07:00
73771a263a remove id for now, use string instead of base64
All checks were successful
Tests / Tests (pull_request) Successful in 16s
2024-11-07 17:08:35 -08:00
655e59c43c Remove base64 scalar 2024-11-07 17:43:09 -07:00
056120a68a Merge pull request 'Add operation for FindPrerecordTableLayoutMutation + HomographyInfoGql fragment' (#121) from loewy/add-operation-check-homography into master
Reviewed-on: #121
2024-11-07 16:51:16 -07:00
bd7ffa7fdb add operation
All checks were successful
Tests / Tests (pull_request) Successful in 10s
2024-11-07 15:45:03 -08:00
ec58923c65 Add id to homography info gql 2024-11-07 16:29:33 -07:00
63869cd7ca Rename checkHomographyIsValid to findPrerecordTableLayout 2024-11-07 15:55:23 -07:00
08ae9611cf Add id to video processing gql 2024-11-07 15:52:07 -07:00
4e610b7df2 Merge pull request 'Return video processing status in feed' (#119) from kat/current-processing into master
Reviewed-on: #119
2024-11-06 22:41:30 -07:00
2d6d3964ad Return video processing status in feed
All checks were successful
Tests / Tests (pull_request) Successful in 8s
2024-11-06 22:40:18 -07:00
73a58de36e Merge pull request 'Make check homography mutation' (#118) from mk/make-homography-mutation into master
Reviewed-on: #118
2024-11-06 17:26:27 -07:00
dc6f246489 Make check homography mutation
All checks were successful
Tests / Tests (pull_request) Successful in 16s
2024-11-06 16:25:23 -08:00
4 changed files with 283 additions and 161 deletions

View File

@@ -184,6 +184,7 @@ export type DoesNotOwnShotErrOtherErrorNeedsNote =
export type EditUserInputGql = { export type EditUserInputGql = {
fargoRating?: InputMaybe<Scalars["Int"]["input"]>; fargoRating?: InputMaybe<Scalars["Int"]["input"]>;
username?: InputMaybe<Scalars["String"]["input"]>; username?: InputMaybe<Scalars["String"]["input"]>;
videosPrivateByDefault?: InputMaybe<Scalars["Boolean"]["input"]>;
}; };
export type EnumAggregation = { export type EnumAggregation = {
@@ -1942,6 +1943,7 @@ export type HomographyInfoGql = {
crop: BoundingBoxGql; crop: BoundingBoxGql;
destPoints: PocketPointsGql; destPoints: PocketPointsGql;
frameIndex: Scalars["Int"]["output"]; frameIndex: Scalars["Int"]["output"];
id: Scalars["Int"]["output"];
pockets: Array<BoundingBoxGql>; pockets: Array<BoundingBoxGql>;
sourcePoints: PocketPointsGql; sourcePoints: PocketPointsGql;
}; };
@@ -2008,6 +2010,7 @@ export type Mutation = {
editProfileImageUri: UserGql; editProfileImageUri: UserGql;
editUploadStream: Scalars["Boolean"]["output"]; editUploadStream: Scalars["Boolean"]["output"];
editUser: UserGql; editUser: UserGql;
findPrerecordTableLayout?: Maybe<HomographyInfoGql>;
followUser: UserGql; followUser: UserGql;
getHlsInitUploadLink: GetUploadLinkReturn; getHlsInitUploadLink: GetUploadLinkReturn;
getProfileImageUploadLink: GetProfileUploadLinkReturn; getProfileImageUploadLink: GetProfileUploadLinkReturn;
@@ -2049,6 +2052,11 @@ export type MutationEditUserArgs = {
input: EditUserInputGql; input: EditUserInputGql;
}; };
export type MutationFindPrerecordTableLayoutArgs = {
b64Image: Scalars["String"]["input"];
videoId: Scalars["Int"]["input"];
};
export type MutationFollowUserArgs = { export type MutationFollowUserArgs = {
followedUserId: Scalars["Int"]["input"]; followedUserId: Scalars["Int"]["input"];
}; };
@@ -2163,7 +2171,6 @@ export enum ProcessingStatusEnum {
export type Query = { export type Query = {
__typename?: "Query"; __typename?: "Query";
checkHomographyIsValid?: Maybe<HomographyInfoGql>;
doesUsernameExist: Scalars["Boolean"]["output"]; doesUsernameExist: Scalars["Boolean"]["output"];
getAggregatedShotMetrics: Array<AggregateResultGql>; getAggregatedShotMetrics: Array<AggregateResultGql>;
getBucketSet?: Maybe<BucketSetGql>; getBucketSet?: Maybe<BucketSetGql>;
@@ -2188,11 +2195,6 @@ export type Query = {
waitFor: Scalars["Float"]["output"]; waitFor: Scalars["Float"]["output"];
}; };
export type QueryCheckHomographyIsValidArgs = {
b64Image: Scalars["String"]["input"];
videoId: Scalars["Int"]["input"];
};
export type QueryDoesUsernameExistArgs = { export type QueryDoesUsernameExistArgs = {
candidateUsername: Scalars["String"]["input"]; candidateUsername: Scalars["String"]["input"];
}; };
@@ -2583,6 +2585,7 @@ export type UserGql = {
profileImageUri?: Maybe<Scalars["String"]["output"]>; profileImageUri?: Maybe<Scalars["String"]["output"]>;
updatedAt?: Maybe<Scalars["DateTime"]["output"]>; updatedAt?: Maybe<Scalars["DateTime"]["output"]>;
username: Scalars["String"]["output"]; username: Scalars["String"]["output"];
videosPrivateByDefault?: Maybe<Scalars["Boolean"]["output"]>;
}; };
export type UserPlayTimeGql = { export type UserPlayTimeGql = {
@@ -2624,6 +2627,7 @@ export type VideoGql = {
name?: Maybe<Scalars["String"]["output"]>; name?: Maybe<Scalars["String"]["output"]>;
owner?: Maybe<UserGql>; owner?: Maybe<UserGql>;
playlist?: Maybe<HlsPlaylistGql>; playlist?: Maybe<HlsPlaylistGql>;
private: Scalars["Boolean"]["output"];
screenshotUri?: Maybe<Scalars["String"]["output"]>; screenshotUri?: Maybe<Scalars["String"]["output"]>;
shots: Array<ShotGql>; shots: Array<ShotGql>;
startTime?: Maybe<Scalars["DateTime"]["output"]>; startTime?: Maybe<Scalars["DateTime"]["output"]>;
@@ -2647,6 +2651,7 @@ export type VideoMetadataInput = {
framesPerSecond?: InputMaybe<Scalars["Float"]["input"]>; framesPerSecond?: InputMaybe<Scalars["Float"]["input"]>;
gameType?: InputMaybe<Scalars["String"]["input"]>; gameType?: InputMaybe<Scalars["String"]["input"]>;
lastIntendedSegmentBound?: InputMaybe<Scalars["Int"]["input"]>; lastIntendedSegmentBound?: InputMaybe<Scalars["Int"]["input"]>;
private?: InputMaybe<Scalars["Boolean"]["input"]>;
resolution?: InputMaybe<VideoResolution>; resolution?: InputMaybe<VideoResolution>;
startTime?: InputMaybe<Scalars["DateTime"]["input"]>; startTime?: InputMaybe<Scalars["DateTime"]["input"]>;
streamSegmentType?: InputMaybe<StreamSegmentTypeEnum>; streamSegmentType?: InputMaybe<StreamSegmentTypeEnum>;
@@ -2664,6 +2669,7 @@ export type VideoProcessingErrorGql = {
export type VideoProcessingGql = { export type VideoProcessingGql = {
__typename?: "VideoProcessingGQL"; __typename?: "VideoProcessingGQL";
errors: Array<VideoProcessingErrorGql>; errors: Array<VideoProcessingErrorGql>;
id: Scalars["Int"]["output"];
status: ProcessingStatusEnum; status: ProcessingStatusEnum;
statuses: Array<VideoProcessingStatusGql>; statuses: Array<VideoProcessingStatusGql>;
}; };
@@ -2822,6 +2828,16 @@ export type VideoCardFieldsFragment = {
name: string; name: string;
tagClasses: Array<{ __typename?: "VideoTagClass"; name: string }>; tagClasses: Array<{ __typename?: "VideoTagClass"; name: string }>;
}>; }>;
currentProcessing?: {
__typename?: "VideoProcessingGQL";
id: number;
status: ProcessingStatusEnum;
errors: Array<{ __typename?: "VideoProcessingErrorGQL"; message: string }>;
statuses: Array<{
__typename?: "VideoProcessingStatusGQL";
status: ProcessingStatusEnum;
}>;
} | null;
}; };
export type GetVideoFeedQueryVariables = Exact<{ export type GetVideoFeedQueryVariables = Exact<{
@@ -2864,6 +2880,19 @@ export type GetVideoFeedQuery = {
name: string; name: string;
tagClasses: Array<{ __typename?: "VideoTagClass"; name: string }>; tagClasses: Array<{ __typename?: "VideoTagClass"; name: string }>;
}>; }>;
currentProcessing?: {
__typename?: "VideoProcessingGQL";
id: number;
status: ProcessingStatusEnum;
errors: Array<{
__typename?: "VideoProcessingErrorGQL";
message: string;
}>;
statuses: Array<{
__typename?: "VideoProcessingStatusGQL";
status: ProcessingStatusEnum;
}>;
} | null;
}>; }>;
pageInfo: { pageInfo: {
__typename?: "PageInfoGQL"; __typename?: "PageInfoGQL";
@@ -3423,6 +3452,8 @@ export type GetStreamMonitoringDetailsQuery = {
elapsedTime?: number | null; elapsedTime?: number | null;
currentHomography?: { currentHomography?: {
__typename?: "HomographyInfoGQL"; __typename?: "HomographyInfoGQL";
id: number;
frameIndex: number;
crop: { crop: {
__typename?: "BoundingBoxGQL"; __typename?: "BoundingBoxGQL";
left: number; left: number;
@@ -3636,6 +3667,7 @@ export type GetVideoQuery = {
} | null; } | null;
homographyHistory: Array<{ homographyHistory: Array<{
__typename?: "HomographyInfoGQL"; __typename?: "HomographyInfoGQL";
id: number;
frameIndex: number; frameIndex: number;
crop: { crop: {
__typename?: "BoundingBoxGQL"; __typename?: "BoundingBoxGQL";
@@ -3837,6 +3869,72 @@ export type GetHeaderInfoByVideoIdQuery = {
}; };
}; };
export type FindPrerecordTableLayoutMutationVariables = Exact<{
b64Image: Scalars["String"]["input"];
videoId: Scalars["Int"]["input"];
}>;
export type FindPrerecordTableLayoutMutation = {
__typename?: "Mutation";
findPrerecordTableLayout?: {
__typename?: "HomographyInfoGQL";
id: number;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
left: number;
top: number;
width: number;
height: number;
};
pockets: Array<{
__typename?: "BoundingBoxGQL";
left: number;
top: number;
width: number;
height: number;
}>;
sourcePoints: {
__typename?: "PocketPointsGQL";
topLeft: { __typename?: "IntPoint2D"; x: number; y: number };
topSide: { __typename?: "IntPoint2D"; x: number; y: number };
topRight: { __typename?: "IntPoint2D"; x: number; y: number };
bottomLeft: { __typename?: "IntPoint2D"; x: number; y: number };
bottomSide: { __typename?: "IntPoint2D"; x: number; y: number };
bottomRight: { __typename?: "IntPoint2D"; x: number; y: number };
};
} | null;
};
export type HomographyInfoFragment = {
__typename?: "HomographyInfoGQL";
id: number;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
left: number;
top: number;
width: number;
height: number;
};
pockets: Array<{
__typename?: "BoundingBoxGQL";
left: number;
top: number;
width: number;
height: number;
}>;
sourcePoints: {
__typename?: "PocketPointsGQL";
topLeft: { __typename?: "IntPoint2D"; x: number; y: number };
topSide: { __typename?: "IntPoint2D"; x: number; y: number };
topRight: { __typename?: "IntPoint2D"; x: number; y: number };
bottomLeft: { __typename?: "IntPoint2D"; x: number; y: number };
bottomSide: { __typename?: "IntPoint2D"; x: number; y: number };
bottomRight: { __typename?: "IntPoint2D"; x: number; y: number };
};
};
export type CreateUploadStreamMutationVariables = Exact<{ export type CreateUploadStreamMutationVariables = Exact<{
videoMetadataInput: VideoMetadataInput; videoMetadataInput: VideoMetadataInput;
}>; }>;
@@ -4039,6 +4137,16 @@ export const VideoCardFieldsFragmentDoc = gql`
} }
name name
} }
currentProcessing {
id
errors {
message
}
status
statuses {
status
}
}
} }
`; `;
export const ShotWithAllFeaturesFragmentDoc = gql` export const ShotWithAllFeaturesFragmentDoc = gql`
@@ -4159,6 +4267,50 @@ export const VideoDurationDataFragmentDoc = gql`
${PlaylistWithSegmentStartTimesFragmentDoc} ${PlaylistWithSegmentStartTimesFragmentDoc}
${StreamWithEndFramesFragmentDoc} ${StreamWithEndFramesFragmentDoc}
`; `;
export const HomographyInfoFragmentDoc = gql`
fragment HomographyInfo on HomographyInfoGQL {
id
frameIndex
crop {
left
top
width
height
}
pockets {
left
top
width
height
}
sourcePoints {
topLeft {
x
y
}
topSide {
x
y
}
topRight {
x
y
}
bottomLeft {
x
y
}
bottomSide {
x
y
}
bottomRight {
x
y
}
}
}
`;
export const GetAggregatedShotMetricsDocument = gql` export const GetAggregatedShotMetricsDocument = gql`
query GetAggregatedShotMetrics($aggregateInput: AggregateInputGQL!) { query GetAggregatedShotMetrics($aggregateInput: AggregateInputGQL!) {
getAggregatedShotMetrics(aggregateInput: $aggregateInput) { getAggregatedShotMetrics(aggregateInput: $aggregateInput) {
@@ -6031,44 +6183,7 @@ export const GetStreamMonitoringDetailsDocument = gql`
makePercentage makePercentage
elapsedTime elapsedTime
currentHomography { currentHomography {
crop { ...HomographyInfo
left
top
width
height
}
pockets {
left
top
width
height
}
sourcePoints {
topLeft {
x
y
}
topSide {
x
y
}
topRight {
x
y
}
bottomLeft {
x
y
}
bottomSide {
x
y
}
bottomRight {
x
y
}
}
} }
stream { stream {
id id
@@ -6089,6 +6204,7 @@ export const GetStreamMonitoringDetailsDocument = gql`
} }
} }
} }
${HomographyInfoFragmentDoc}
`; `;
/** /**
@@ -6538,45 +6654,7 @@ export const GetVideoDocument = gql`
segmentDurations segmentDurations
} }
homographyHistory { homographyHistory {
frameIndex ...HomographyInfo
crop {
left
top
width
height
}
pockets {
left
top
width
height
}
sourcePoints {
topLeft {
x
y
}
topSide {
x
y
}
topRight {
x
y
}
bottomLeft {
x
y
}
bottomSide {
x
y
}
bottomRight {
x
y
}
}
} }
stream { stream {
id id
@@ -6593,6 +6671,7 @@ export const GetVideoDocument = gql`
} }
} }
} }
${HomographyInfoFragmentDoc}
`; `;
/** /**
@@ -7026,6 +7105,59 @@ export type GetHeaderInfoByVideoIdQueryResult = Apollo.QueryResult<
GetHeaderInfoByVideoIdQuery, GetHeaderInfoByVideoIdQuery,
GetHeaderInfoByVideoIdQueryVariables GetHeaderInfoByVideoIdQueryVariables
>; >;
export const FindPrerecordTableLayoutDocument = gql`
mutation FindPrerecordTableLayout($b64Image: String!, $videoId: Int!) {
findPrerecordTableLayout(b64Image: $b64Image, videoId: $videoId) {
...HomographyInfo
}
}
${HomographyInfoFragmentDoc}
`;
export type FindPrerecordTableLayoutMutationFn = Apollo.MutationFunction<
FindPrerecordTableLayoutMutation,
FindPrerecordTableLayoutMutationVariables
>;
/**
* __useFindPrerecordTableLayoutMutation__
*
* To run a mutation, you first call `useFindPrerecordTableLayoutMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useFindPrerecordTableLayoutMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [findPrerecordTableLayoutMutation, { data, loading, error }] = useFindPrerecordTableLayoutMutation({
* variables: {
* b64Image: // value for 'b64Image'
* videoId: // value for 'videoId'
* },
* });
*/
export function useFindPrerecordTableLayoutMutation(
baseOptions?: Apollo.MutationHookOptions<
FindPrerecordTableLayoutMutation,
FindPrerecordTableLayoutMutationVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useMutation<
FindPrerecordTableLayoutMutation,
FindPrerecordTableLayoutMutationVariables
>(FindPrerecordTableLayoutDocument, options);
}
export type FindPrerecordTableLayoutMutationHookResult = ReturnType<
typeof useFindPrerecordTableLayoutMutation
>;
export type FindPrerecordTableLayoutMutationResult =
Apollo.MutationResult<FindPrerecordTableLayoutMutation>;
export type FindPrerecordTableLayoutMutationOptions =
Apollo.BaseMutationOptions<
FindPrerecordTableLayoutMutation,
FindPrerecordTableLayoutMutationVariables
>;
export const CreateUploadStreamDocument = gql` export const CreateUploadStreamDocument = gql`
mutation CreateUploadStream($videoMetadataInput: VideoMetadataInput!) { mutation CreateUploadStream($videoMetadataInput: VideoMetadataInput!) {
createUploadStream(videoMetadata: $videoMetadataInput) { createUploadStream(videoMetadata: $videoMetadataInput) {

View File

@@ -69,6 +69,16 @@ fragment VideoCardFields on VideoGQL {
} }
name name
} }
currentProcessing {
id
errors {
message
}
status
statuses {
status
}
}
} }
query GetVideoFeed( query GetVideoFeed(

View File

@@ -5,44 +5,7 @@ query GetStreamMonitoringDetails($videoId: Int!, $debuggingJson: JSON) {
makePercentage makePercentage
elapsedTime elapsedTime
currentHomography { currentHomography {
crop { ...HomographyInfo
left
top
width
height
}
pockets {
left
top
width
height
}
sourcePoints {
topLeft {
x
y
}
topSide {
x
y
}
topRight {
x
y
}
bottomLeft {
x
y
}
bottomSide {
x
y
}
bottomRight {
x
y
}
}
} }
stream { stream {
id id
@@ -154,45 +117,7 @@ query GetVideo($videoId: Int!) {
segmentDurations segmentDurations
} }
homographyHistory { homographyHistory {
frameIndex ...HomographyInfo
crop {
left
top
width
height
}
pockets {
left
top
width
height
}
sourcePoints {
topLeft {
x
y
}
topSide {
x
y
}
topRight {
x
y
}
bottomLeft {
x
y
}
bottomSide {
x
y
}
bottomRight {
x
y
}
}
} }
stream { stream {
id id
@@ -288,3 +213,52 @@ query GetHeaderInfoByVideoId($videoId: Int!) {
startTime startTime
} }
} }
mutation FindPrerecordTableLayout($b64Image: String!, $videoId: Int!) {
findPrerecordTableLayout(b64Image: $b64Image, videoId: $videoId) {
...HomographyInfo
}
}
fragment HomographyInfo on HomographyInfoGQL {
id
frameIndex
crop {
left
top
width
height
}
pockets {
left
top
width
height
}
sourcePoints {
topLeft {
x
y
}
topSide {
x
y
}
topRight {
x
y
}
bottomLeft {
x
y
}
bottomSide {
x
y
}
bottomRight {
x
y
}
}
}

View File

@@ -56,7 +56,6 @@ type Query {
getUserTags: [TagGQL!]! getUserTags: [TagGQL!]!
getVideo(videoId: Int!, debuggingJson: JSON = null): VideoGQL! getVideo(videoId: Int!, debuggingJson: JSON = null): VideoGQL!
getVideos(videoIds: [Int!]!): [VideoGQL!]! getVideos(videoIds: [Int!]!): [VideoGQL!]!
checkHomographyIsValid(b64Image: String!, videoId: Int!): HomographyInfoGQL
getFeedVideos( getFeedVideos(
limit: Int! = 5 limit: Int! = 5
after: String = null after: String = null
@@ -401,6 +400,7 @@ type UserGQL {
profileImageUri: String profileImageUri: String
createdAt: DateTime createdAt: DateTime
updatedAt: DateTime updatedAt: DateTime
videosPrivateByDefault: Boolean
following: [UserGQL!] following: [UserGQL!]
followers: [UserGQL!] followers: [UserGQL!]
} }
@@ -438,6 +438,7 @@ type VideoGQL {
elapsedTime: Float elapsedTime: Float
framesPerSecond: Float! framesPerSecond: Float!
tableSize: Float! tableSize: Float!
private: Boolean!
stream: UploadStreamGQL stream: UploadStreamGQL
playlist: HLSPlaylistGQL playlist: HLSPlaylistGQL
tags: [VideoTag!]! tags: [VideoTag!]!
@@ -510,6 +511,7 @@ type VideoTagClass {
} }
type HomographyInfoGQL { type HomographyInfoGQL {
id: Int!
frameIndex: Int! frameIndex: Int!
crop: BoundingBoxGQL! crop: BoundingBoxGQL!
pockets: [BoundingBoxGQL!]! pockets: [BoundingBoxGQL!]!
@@ -539,6 +541,7 @@ type IntPoint2D {
} }
type VideoProcessingGQL { type VideoProcessingGQL {
id: Int!
errors: [VideoProcessingErrorGQL!]! errors: [VideoProcessingErrorGQL!]!
status: ProcessingStatusEnum! status: ProcessingStatusEnum!
statuses: [VideoProcessingStatusGQL!]! statuses: [VideoProcessingStatusGQL!]!
@@ -669,6 +672,7 @@ type Mutation {
editUser(input: EditUserInputGQL!): UserGQL! editUser(input: EditUserInputGQL!): UserGQL!
followUser(followedUserId: Int!): UserGQL! followUser(followedUserId: Int!): UserGQL!
unfollowUser(followedUserId: Int!): UserGQL! unfollowUser(followedUserId: Int!): UserGQL!
findPrerecordTableLayout(b64Image: String!, videoId: Int!): HomographyInfoGQL
createUploadStream( createUploadStream(
videoMetadata: VideoMetadataInput! videoMetadata: VideoMetadataInput!
): CreateUploadStreamReturn! ): CreateUploadStreamReturn!
@@ -757,6 +761,7 @@ type TooManyProfileImageUploadsErr {
input EditUserInputGQL { input EditUserInputGQL {
username: String = null username: String = null
fargoRating: Int = null fargoRating: Int = null
videosPrivateByDefault: Boolean = null
} }
type CreateUploadStreamReturn { type CreateUploadStreamReturn {
@@ -771,6 +776,7 @@ input VideoMetadataInput {
tableSize: Float = null tableSize: Float = null
lastIntendedSegmentBound: Int = null lastIntendedSegmentBound: Int = null
streamSegmentType: StreamSegmentTypeEnum = null streamSegmentType: StreamSegmentTypeEnum = null
private: Boolean = null
endStream: Boolean! = false endStream: Boolean! = false
resolution: VideoResolution = null resolution: VideoResolution = null
framesPerSecond: Float = null framesPerSecond: Float = null