Reworked FFMPeg player UI. It's almost useful now

This commit is contained in:
Zakk 2016-06-27 04:06:03 -04:00
parent 72cb859148
commit 127f5933e8
20 changed files with 550 additions and 125 deletions

View file

@ -12,6 +12,7 @@
34BDCD651D10F4E100F51996 /* CSFFMpegCaptureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34BDCD631D10F4E100F51996 /* CSFFMpegCaptureViewController.m */; };
34BDCD661D10F4E100F51996 /* CSFFMpegCaptureViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34BDCD641D10F4E100F51996 /* CSFFMpegCaptureViewController.xib */; };
34BDCD7D1D14178800F51996 /* CSFFMpegPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34BDCD7C1D14178800F51996 /* CSFFMpegPlayer.m */; };
34BDCD7F1D1FE4A700F51996 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 34BDCD7E1D1FE4A700F51996 /* Media.xcassets */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -39,6 +40,7 @@
34BDCD641D10F4E100F51996 /* CSFFMpegCaptureViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CSFFMpegCaptureViewController.xib; sourceTree = "<group>"; };
34BDCD7B1D14178800F51996 /* CSFFMpegPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSFFMpegPlayer.h; sourceTree = "<group>"; };
34BDCD7C1D14178800F51996 /* CSFFMpegPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSFFMpegPlayer.m; sourceTree = "<group>"; };
34BDCD7E1D1FE4A700F51996 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -55,6 +57,7 @@
343C79B11D0C763A00B36EEC = {
isa = PBXGroup;
children = (
34BDCD7E1D1FE4A700F51996 /* Media.xcassets */,
343C79E91D0C769100B36EEC /* PluginHeaders */,
343C79BC1D0C763A00B36EEC /* CSFFMpegCapturePlugin */,
343C79BB1D0C763A00B36EEC /* Products */,
@ -163,6 +166,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
34BDCD7F1D1FE4A700F51996 /* Media.xcassets in Resources */,
34BDCD661D10F4E100F51996 /* CSFFMpegCaptureViewController.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;

View file

@ -44,7 +44,6 @@
}
@property (strong) NSString *inputPath;
@property (strong) CSPcmPlayer *pcmPlayer;
@property (strong) CSFFMpegPlayer *player;
@ -55,5 +54,12 @@
@property (assign) double currentMovieDuration;
-(void)queuePath:(NSString *)path;
-(void)pause;
-(void)play;
-(void)mute;
-(void)next;
-(void)back;
@end

View file

@ -10,7 +10,6 @@
@implementation CSFFMpegCapture
@synthesize inputPath = _inputPath;
@synthesize currentMovieTime = _currentMovieTime;
-(instancetype) init
@ -44,6 +43,60 @@
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
NSMutableArray *queuePaths = [[NSMutableArray alloc] init];
for (CSFFMpegInput *inp in self.player.inputQueue)
{
[queuePaths addObject:inp.mediaPath];
}
[aCoder encodeObject:queuePaths forKey:@"queuePaths"];
CSFFMpegInput *nowPlaying = self.player.currentlyPlaying;
NSString *nPath = nil;
if (nowPlaying)
{
nPath = nowPlaying.mediaPath;
}
[aCoder encodeObject:nPath forKey:@"nowPlayingPath"];
}
-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [self init])
{
CSFFMpegInput *nowPlayingInput = nil;
NSString *nowPlayingPath = [aDecoder decodeObjectForKey:@"nowPlayingPath"];
NSArray *paths = [aDecoder decodeObjectForKey:@"queuePaths"];
for (NSString *mPath in paths)
{
CSFFMpegInput *newInput = [[CSFFMpegInput alloc] initWithMediaPath:mPath];
[self.player enqueueItem:newInput];
if (nowPlayingPath && [newInput.mediaPath isEqualToString:nowPlayingPath])
{
nowPlayingInput = newInput;
}
}
if (nowPlayingInput)
{
self.player.currentlyPlaying = nowPlayingInput;
}
}
return self;
}
+(NSString *)label
{
return @"FFMPegPlayer";
@ -76,25 +129,58 @@
}
-(NSString *)inputPath
-(void)queuePath:(NSString *)path
{
return _inputPath;
}
-(void)setInputPath:(NSString *)inputPath
{
_inputPath = inputPath;
if (!self.player.pcmPlayer && self.pcmPlayer)
{
self.player.pcmPlayer = self.pcmPlayer;
}
CSFFMpegInput *newItem = [[CSFFMpegInput alloc] initWithMediaPath:_inputPath];
CSFFMpegInput *newItem = [[CSFFMpegInput alloc] initWithMediaPath:path];
[self.player enqueueItem:newItem ];
[self.player play];
}
-(void)pause
{
if (self.player)
{
[self.player pause];
}
}
-(void)play
{
if (self.player)
{
[self.player play];
}
}
-(void)mute
{
if (self.player)
{
self.player.muted = !self.player.muted;
}
}
-(void)next
{
if (self.player)
{
[self.player next];
}
}
-(void)back
{
if (self.player)
{
[self.player back];
}
}

View file

@ -12,11 +12,17 @@
@interface CSFFMpegCaptureViewController : NSViewController
@property (weak) CSFFMpegCapture *captureObj;
@property (weak) IBOutlet NSSegmentedControl *playlistControl;
@property (strong) IBOutlet NSArrayController *queueArrayController;
- (IBAction)queueTableDoubleClick:(NSTableView *)sender;
- (IBAction)chooseFile:(id)sender;
- (IBAction)nextAction:(id)sender;
- (IBAction)sliderValueChanged:(id)sender;
- (IBAction)pauseAction:(id)sender;
- (IBAction)tableControlAction:(NSSegmentedControl *)sender;
@end

View file

@ -17,39 +17,95 @@
- (void)viewDidLoad {
[super viewDidLoad];
// Do view setup here.
if (self.captureObj && self.captureObj.player)
{
self.captureObj.player.pauseStateChanged = ^{
[self pauseStateChanged];
};
}
}
- (IBAction)queueTableDoubleClick:(NSTableView *)sender
{
CSFFMpegInput *inp = [self.queueArrayController.arrangedObjects objectAtIndex:sender.clickedRow];
if (inp)
{
[self.captureObj.player playAndAddItem:inp];
}
}
- (IBAction)chooseFile:(id)sender
{
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.canChooseDirectories = NO;
panel.canCreateDirectories = YES;
panel.canCreateDirectories = NO;
panel.canChooseFiles = YES;
panel.allowsMultipleSelection = NO;
panel.allowsMultipleSelection = YES;
[panel beginWithCompletionHandler:^(NSInteger result) {
if (result == NSFileHandlingPanelOKButton)
{
self.captureObj.inputPath = panel.URL.path;
for (NSURL *openURL in panel.URLs)
{
[self.captureObj queuePath:openURL.path];
}
}
}];
}
- (IBAction)pauseAction:(id)sender
- (IBAction)tableControlAction:(NSSegmentedControl *)sender
{
[self.captureObj.player pause];
NSUInteger clicked = sender.selectedSegment;
switch (clicked)
{
case 0:
[self.queueArrayController removeObjectsAtArrangedObjectIndexes:self.queueArrayController.selectionIndexes];
break;
case 1:
[self.captureObj back];
break;
case 2:
if (!self.captureObj.player.playing || self.captureObj.player.paused)
{
[self.captureObj play];
} else {
[self.captureObj pause];
}
break;
case 3:
[self.captureObj next];
break;
}
}
- (IBAction)nextAction:(id)sender
{
[self.captureObj.player next];
}
-(void)pauseStateChanged
{
dispatch_async(dispatch_get_main_queue(), ^{
if (self.captureObj.player.paused)
{
NSImage *playImage = [[NSBundle bundleForClass:[self class]] imageForResource:@"play"];
[self.playlistControl setImage:playImage forSegment:2];
} else {
NSImage *pauseImage = [[NSBundle bundleForClass:[self class]] imageForResource:@"pause"];
[self.playlistControl setImage:pauseImage forSegment:2];
}
});
}
- (IBAction)sliderValueChanged:(id)sender
{
NSEvent *event = [[NSApplication sharedApplication] currentEvent];
@ -59,15 +115,12 @@
if (startingDrag) {
self.captureObj.player.muted = YES;
self.captureObj.player.seeking = YES;
[self.captureObj mute];
}
if (endingDrag) {
self.captureObj.player.muted = NO;
self.captureObj.player.seeking = NO;
self.captureObj.player.audio_needs_restart = YES;
[self.captureObj mute];
}
}

View file

@ -7,6 +7,8 @@
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="CSFFMpegCaptureViewController">
<connections>
<outlet property="playlistControl" destination="QyX-l5-Nc5" id="w6z-OF-Sap"/>
<outlet property="queueArrayController" destination="IJW-AP-l9B" id="Iav-jl-1Al"/>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
@ -16,59 +18,28 @@
<rect key="frame" x="0.0" y="0.0" width="480" height="274"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rMk-Ss-9DA">
<rect key="frame" x="-2" y="249" width="35" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Item:" id="p7M-Xi-1dn">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vOl-es-UsB">
<rect key="frame" x="57" y="231" width="248" height="22"/>
<rect key="frame" x="35" y="216" width="248" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="aCx-uQ-Hyw">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="oEH-Pr-eH8" name="value" keyPath="selection.inputPath" id="dmz-zG-WPz"/>
</connections>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lvV-HJ-t1F">
<rect key="frame" x="307" y="225" width="85" height="32"/>
<buttonCell key="cell" type="push" title="Browse" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Vlz-7L-vXD">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="chooseFile:" target="-2" id="upc-a7-d92"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9dn-Q6-tui">
<rect key="frame" x="387" y="224" width="69" height="32"/>
<buttonCell key="cell" type="push" title="Next" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="zd9-c9-lRF">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="nextAction:" target="-2" id="alT-t7-mie"/>
</connections>
</button>
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f41-BA-QN1">
<rect key="frame" x="0.0" y="51" width="480" height="173"/>
<rect key="frame" x="0.0" y="51" width="480" height="160"/>
<clipView key="contentView" ambiguous="YES" id="brZ-Ue-OlN">
<rect key="frame" x="1" y="1" width="478" height="171"/>
<rect key="frame" x="1" y="1" width="478" height="158"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="I07-lW-ske">
<rect key="frame" x="0.0" y="0.0" width="478" height="171"/>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="I07-lW-ske">
<rect key="frame" x="0.0" y="0.0" width="478" height="158"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="437.734375" minWidth="40" maxWidth="1000" id="Nwb-J9-jgx">
<tableColumn width="475" minWidth="40" maxWidth="1000" id="Nwb-J9-jgx">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@ -82,7 +53,7 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="RQg-6s-vBV">
<rect key="frame" x="1" y="1" width="438" height="17"/>
<rect key="frame" x="1" y="1" width="475" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="D02-lA-vKn">
@ -93,7 +64,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="RQg-6s-vBV" name="value" keyPath="objectValue.mediaPath" id="DYO-rY-SK9"/>
<binding destination="RQg-6s-vBV" name="value" keyPath="objectValue.shortName" id="Keo-yR-kdF"/>
</connections>
</textField>
</subviews>
@ -105,14 +76,16 @@
</tableColumn>
</tableColumns>
<connections>
<action trigger="doubleAction" selector="queueTableDoubleClick:" target="-2" id="DqU-hT-tKe"/>
<binding destination="IJW-AP-l9B" name="content" keyPath="arrangedObjects" id="Obn-rt-gTO"/>
<binding destination="IJW-AP-l9B" name="selectionIndexes" keyPath="selectionIndexes" previousBinding="Obn-rt-gTO" id="uSY-FM-WQr"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="nop-yY-vCc">
<rect key="frame" x="1" y="119" width="223" height="15"/>
<rect key="frame" x="1" y="-14" width="0.0" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="v3c-hU-RoT">
@ -120,8 +93,19 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SXP-7Z-utT">
<rect key="frame" x="-2" y="11" width="53" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="4Uo-PT-atT">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.captureObj.currentTimeString" id="00c-WM-D7h"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0A5-wU-ykQ">
<rect key="frame" x="426" y="26" width="56" height="17"/>
<rect key="frame" x="426" y="11" width="56" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="geK-QL-6Yn">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -132,7 +116,7 @@
</connections>
</textField>
<slider verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6Ff-r4-Piz">
<rect key="frame" x="41" y="24" width="381" height="21"/>
<rect key="frame" x="41" y="9" width="381" height="21"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="100" doubleValue="50" tickMarkPosition="above" sliderType="linear" id="0CD-ye-G7q"/>
<connections>
<action selector="sliderValueChanged:" target="-2" id="n3I-VU-HBB"/>
@ -140,29 +124,70 @@
<binding destination="oEH-Pr-eH8" name="value" keyPath="selection.currentMovieTime" previousBinding="tY5-ux-rot" id="3WD-8m-Go4"/>
</connections>
</slider>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GVe-Io-bJG">
<rect key="frame" x="261" y="-7" width="77" height="32"/>
<buttonCell key="cell" type="push" title="Pause" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="GtF-SP-Tyu">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<segmentedControl verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QyX-l5-Nc5">
<rect key="frame" x="0.0" y="35" width="480" height="19"/>
<segmentedCell key="cell" controlSize="mini" borderStyle="border" alignment="left" style="smallSquare" trackingMode="momentary" id="qwJ-2s-Umv">
<font key="font" metaFont="miniSystem"/>
<segments>
<segment image="NSRemoveTemplate"/>
<segment image="rewind" tag="1"/>
<segment image="play">
<nil key="label"/>
</segment>
<segment image="fastforward">
<nil key="label"/>
</segment>
<segment width="380" enabled="NO" tag="4">
<nil key="label"/>
</segment>
</segments>
</segmentedCell>
<connections>
<action selector="pauseAction:" target="-2" id="orY-mY-XAX"/>
<action selector="tableControlAction:" target="-2" id="iax-05-x1c"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SXP-7Z-utT">
<rect key="frame" x="-2" y="26" width="53" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="4Uo-PT-atT">
</segmentedControl>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rMk-Ss-9DA">
<rect key="frame" x="-2" y="219" width="32" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Add:" id="p7M-Xi-1dn">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pyb-Oa-cTq">
<rect key="frame" x="-2" y="251" width="52" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Playing:" id="b9z-O4-d9f">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Taf-5T-FT6">
<rect key="frame" x="54" y="251" width="428" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="jIY-LY-9hI">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="value" keyPath="self.captureObj.currentTimeString" id="00c-WM-D7h"/>
<binding destination="oEH-Pr-eH8" name="value" keyPath="selection.player.currentlyPlaying.shortName" id="xPc-Ft-0kn"/>
</connections>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lvV-HJ-t1F">
<rect key="frame" x="285" y="210" width="85" height="32"/>
<buttonCell key="cell" type="push" title="Browse" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Vlz-7L-vXD">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="chooseFile:" target="-2" id="upc-a7-d92"/>
</connections>
</button>
</subviews>
<point key="canvasLocation" x="427" y="352"/>
<constraints>
<constraint firstItem="QyX-l5-Nc5" firstAttribute="top" secondItem="I07-lW-ske" secondAttribute="bottom" constant="-1" id="fLU-Tx-cYu"/>
</constraints>
<point key="canvasLocation" x="671" y="456"/>
</customView>
<objectController id="oEH-Pr-eH8" userLabel="FFmpegCaptureController">
<connections>
@ -175,4 +200,10 @@
</connections>
</arrayController>
</objects>
<resources>
<image name="NSRemoveTemplate" width="11" height="11"/>
<image name="fastforward" width="74.400001525878906" height="58.400001525878906"/>
<image name="play" width="50.400001525878906" height="58.400001525878906"/>
<image name="rewind" width="74.400001525878906" height="58.400001525878906"/>
</resources>
</document>

View file

@ -90,6 +90,7 @@ struct frame_message {
@property (assign) NSSize dimensions;
@property (assign) double duration;
@property (strong) NSString *shortName;
-(AVFrame *)consumeFrame:(int *)error_out;

View file

@ -30,8 +30,6 @@
_seek_queue = dispatch_queue_create("SEEK QUEUE", DISPATCH_QUEUE_SERIAL);
av_thread_message_queue_alloc(&_video_message_queue, 300, sizeof(struct frame_message));
av_thread_message_queue_alloc(&_audio_message_queue, 4096 , sizeof(struct frame_message));
}
return self;
}
@ -41,6 +39,7 @@
if (self = [self init])
{
self.mediaPath = mediaPath;
self.shortName = [mediaPath lastPathComponent];
}
return self;
@ -55,9 +54,28 @@
return NO;
}
if (!_video_message_queue)
{
av_thread_message_queue_alloc(&_video_message_queue, 300, sizeof(struct frame_message));
}
if (!_audio_message_queue)
{
av_thread_message_queue_alloc(&_audio_message_queue, 4096 , sizeof(struct frame_message));
}
av_thread_message_queue_set_err_recv(_video_message_queue, 0);
av_thread_message_queue_set_err_recv(_audio_message_queue, 0);
av_thread_message_queue_set_err_send(_video_message_queue, 0);
av_thread_message_queue_set_err_send(_audio_message_queue, 0);
AVCodecContext *v_codec_ctx_orig = NULL;
AVCodecContext *a_codec_ctx_orig = NULL;
avformat_open_input(&_format_ctx, self.mediaPath.UTF8String, NULL, NULL);
@ -111,8 +129,17 @@
}
self.is_ready = NO;
_stop_request = NO;
self.is_draining = NO;
_video_done = NO;
_audio_done = NO;
self.duration = _format_ctx->duration / (double)AV_TIME_BASE;
[self readAndDecodeVideoFrames:bufferVideoFrames];
@ -338,6 +365,12 @@
-(AVFrame *)consumeFrame:(int *)error_out
{
if (!_video_message_queue)
{
return NULL;
}
if (_video_done)
{
return NULL;
@ -366,6 +399,7 @@
//You should run this is a gcd queue/block
-(void)readAndDecodeVideoFrames:(int)frameCnt
{
@ -389,12 +423,10 @@
while (do_audio || do_video)
{
if (_stop_request)
{
[self closeMedia];
_stop_request = NO;
return;
}
@ -602,6 +634,8 @@
return ret;
}
-(void) closeMedia
{

View file

@ -24,6 +24,8 @@
bool _nextFlag;
int64_t _first_video_pts;
bool _flushAudio;
int _doneDirection;
CSFFMpegInput *_forceNextInput;
@ -40,6 +42,8 @@
@property (assign) AudioStreamBasicDescription *asbd;
@property (copy, nonatomic) void (^itemStarted)(CSFFMpegInput *);
@property (copy, nonatomic) void (^pauseStateChanged)();
@property (assign) double lastVideoTime;
@property (assign) double videoDuration;
@property (assign) bool muted;
@ -51,11 +55,16 @@
-(void)nextItem;
-(void)previousItem;
-(void)enqueueItem:(CSFFMpegInput *)item;
-(void)play;
-(void)stop;
-(void)next;
-(void)pause;
-(void)back;
-(void)playAndAddItem:(CSFFMpegInput *)item;
-(void)seek:(double)toTime;
-(void)startAudio;

View file

@ -23,6 +23,7 @@
_inputQueue = [[NSMutableArray alloc] init];
_nextFlag = NO;
_muted = NO;
_doneDirection = 1;
}
@ -67,9 +68,8 @@
}
-(void)nextItem
-(CSFFMpegInput *)preChangeItem
{
CSFFMpegInput *useItem;
_nextFlag = NO;
@synchronized (self) {
@ -89,22 +89,99 @@
}
}
if (useItem)
{
[useItem closeMedia];
}
return useItem;
}
-(void)previousItem
{
CSFFMpegInput *useItem = [self preChangeItem];
if (!self.playing)
{
return;
}
NSInteger currentIdx = 0;
currentIdx = [_inputQueue indexOfObject:useItem];
currentIdx--;
if (currentIdx < 0)
{
currentIdx = _inputQueue.count-1;
}
CSFFMpegInput *nextItem = [_inputQueue objectAtIndex:currentIdx];
if (nextItem)
{
[self playItem:nextItem];
//[self removeObjectFromInputQueueAtIndex:0];
}
}
-(void)nextItem
{
CSFFMpegInput *useItem = [self preChangeItem];
if (!self.playing)
{
return;
}
CSFFMpegInput *nextItem = _inputQueue.firstObject;
NSUInteger currentIdx = 0;
currentIdx = [_inputQueue indexOfObject:useItem];
currentIdx++;
if (currentIdx >= _inputQueue.count)
{
currentIdx = 0;
}
CSFFMpegInput *nextItem = [_inputQueue objectAtIndex:currentIdx];
if (nextItem)
{
[self playItem:nextItem];
[self removeObjectFromInputQueueAtIndex:0];
//[self removeObjectFromInputQueueAtIndex:0];
}
}
-(void)playAndAddItem:(CSFFMpegInput *)item;
{
if ([_inputQueue indexOfObject:item] == NSNotFound)
{
[self enqueueItem:item];
}
if (!self.playing)
{
self.currentlyPlaying = item;
[self playItem:item];
} else {
_forceNextInput = item;
[self.currentlyPlaying stop];
}
}
-(void)seek:(double)toTime
{
if (self.currentlyPlaying)
@ -155,17 +232,36 @@
{
[self nextItem];
} else {
[self playItem:self.currentlyPlaying];
}
if (self.paused)
{
[self pause];
}
}
-(void)next
{
_flushAudio = YES;
_doneDirection = 1;
[self.currentlyPlaying stop];
}
-(void)back
{
_flushAudio = YES;
if (self.lastVideoTime >= 1.5)
{
[self seek:0.0];
} else {
_doneDirection = -1;
[self.currentlyPlaying stop];
}
}
-(void)stop
{
self.playing = NO;
@ -253,7 +349,6 @@
if (!self.playing) break;
}
NSLog(@"OUT OF LOOP");
_audio_done = YES;
[self inputDone];
}
@ -270,9 +365,15 @@
} else {
self.paused = YES;
}
if (self.pauseStateChanged)
{
self.pauseStateChanged();
}
}
-(CVPixelBufferRef)frameForMediaTime:(CFTimeInterval)mediaTime
{
CSFFMpegInput *_useInput;
@ -286,12 +387,6 @@
return nil;
}
/*
if (!self.playing)
{
return nil;
}*/
AVFrame *use_frame = NULL;
CVPixelBufferRef ret = nil;
@ -407,7 +502,17 @@
{
[self.currentlyPlaying stop];
if (_forceNextInput)
{
[self preChangeItem];
[self playItem:_forceNextInput];
_forceNextInput = nil;
} else if (_doneDirection > 0) {
[self nextItem];
} else if (_doneDirection < 0) {
[self previousItem];
}
}
}

View file

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View file

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "fastforward.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "pause.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

View file

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "play.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "rewind.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -403,7 +403,7 @@
<rect key="frame" x="10" y="33" width="840" height="314"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="6mG-LN-iRu">
<customView misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6mG-LN-iRu">
<rect key="frame" x="652" y="77" width="191" height="149"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NfO-T5-aJZ">
@ -581,7 +581,7 @@
<constraint firstItem="2d4-aU-LWX" firstAttribute="leading" secondItem="eJN-jc-tix" secondAttribute="leading" id="s6x-rs-yfk"/>
</constraints>
</customView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3nh-Gb-0rO">
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3nh-Gb-0rO">
<rect key="frame" x="684" y="261" width="126" height="28"/>
<constraints>
<constraint firstAttribute="width" constant="116" id="eEb-bD-ygR"/>
@ -600,7 +600,7 @@
</binding>
</connections>
</button>
<scrollView autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="b93-ds-aBr">
<scrollView misplaced="YES" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="b93-ds-aBr">
<rect key="frame" x="17" y="35" width="286" height="250"/>
<clipView key="contentView" id="Aem-Ho-CCv">
<rect key="frame" x="1" y="1" width="284" height="248"/>
@ -630,7 +630,7 @@
<outlet property="menu" destination="Wwr-bS-1EX" id="3mz-6W-mQM"/>
</connections>
</scrollView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rzE-ZM-Eom">
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rzE-ZM-Eom">
<rect key="frame" x="684" y="233" width="126" height="28"/>
<buttonCell key="cell" type="push" title="Swap" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="XZO-uo-5LB">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -641,7 +641,7 @@
<binding destination="816" name="hidden" keyPath="self.stagingHidden" id="ugE-6e-RoW"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ben-Kb-lKd">
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ben-Kb-lKd">
<rect key="frame" x="311" y="16" width="20" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="Cwb-GG-7L0"/>
@ -654,7 +654,7 @@
<action selector="inputTableControlClick:" target="816" id="ICl-Td-l8w"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="1" translatesAutoresizingMaskIntoConstraints="NO" id="CqS-aN-OHV">
<button verticalHuggingPriority="750" misplaced="YES" tag="1" translatesAutoresizingMaskIntoConstraints="NO" id="CqS-aN-OHV">
<rect key="frame" x="330" y="16" width="20" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="H5Q-Mo-m1Y"/>
@ -667,7 +667,7 @@
<action selector="inputTableControlClick:" target="816" id="4GJ-kl-e2f"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="2" translatesAutoresizingMaskIntoConstraints="NO" id="fsP-NP-oJi">
<button verticalHuggingPriority="750" misplaced="YES" tag="2" translatesAutoresizingMaskIntoConstraints="NO" id="fsP-NP-oJi">
<rect key="frame" x="349" y="16" width="20" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="cg9-vn-69t"/>
@ -680,7 +680,7 @@
<action selector="inputTableControlClick:" target="816" id="j2n-Fm-bla"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0Lk-ZW-rGZ">
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Lk-ZW-rGZ">
<rect key="frame" x="367" y="16" width="277" height="21"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="overlaps" alignment="center" controlSize="small" lineBreakMode="truncatingTail" enabled="NO" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="F5b-B8-5NC">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -700,7 +700,7 @@
<action selector="openLayoutPopover:" target="816" id="TKb-OS-u5h"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cbi-35-XlE">
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cbi-35-XlE">
<rect key="frame" x="36" y="16" width="267" height="21"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" imagePosition="overlaps" alignment="center" controlSize="small" lineBreakMode="truncatingTail" enabled="NO" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="cLo-Nw-hc7">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -715,7 +715,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fjg-Ru-y5H">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fjg-Ru-y5H">
<rect key="frame" x="309" y="292" width="37" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Inputs" id="IaI-MV-5vZ">
<font key="font" metaFont="smallSystem"/>
@ -723,7 +723,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wNM-ch-Aul">
<scrollView misplaced="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wNM-ch-Aul">
<rect key="frame" x="311" y="35" width="333" height="249"/>
<clipView key="contentView" id="GM4-49-5f1">
<rect key="frame" x="1" y="1" width="331" height="247"/>
@ -1346,10 +1346,10 @@
<rect key="frame" x="10" y="33" width="840" height="314"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jA8-yc-8qt">
<customView translatesAutoresizingMaskIntoConstraints="NO" id="jA8-yc-8qt">
<rect key="frame" x="-3" y="-3" width="280" height="334"/>
<subviews>
<button verticalHuggingPriority="750" misplaced="YES" tag="1" translatesAutoresizingMaskIntoConstraints="NO" id="eYy-bt-k7V">
<button verticalHuggingPriority="750" tag="1" translatesAutoresizingMaskIntoConstraints="NO" id="eYy-bt-k7V">
<rect key="frame" x="136" y="264" width="80" height="28"/>
<constraints>
<constraint firstAttribute="width" constant="70" id="der-Yn-Th6"/>
@ -1362,7 +1362,7 @@
<action selector="openAnimatePopover:" target="816" id="t6K-1W-rOE"/>
</connections>
</button>
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="f0c-55-OoR">
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="f0c-55-OoR">
<rect key="frame" x="131" y="157" width="70" height="28"/>
<constraints>
<constraint firstAttribute="width" constant="60" id="XYx-wi-a1k"/>
@ -1387,7 +1387,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LTd-v8-sVD">
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LTd-v8-sVD">
<rect key="frame" x="136" y="236" width="80" height="28"/>
<buttonCell key="cell" type="push" title="Delete" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="h93-32-Yxb">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -1401,7 +1401,7 @@
</binding>
</connections>
</button>
<scrollView misplaced="YES" autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="10" verticalLineScroll="24" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pBZ-2W-Ihl">
<scrollView autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="10" verticalLineScroll="24" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pBZ-2W-Ihl">
<rect key="frame" x="20" y="20" width="240" height="135"/>
<clipView key="contentView" id="cCv-vT-ucF">
<rect key="frame" x="1" y="1" width="238" height="133"/>
@ -1558,14 +1558,14 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<scrollView misplaced="YES" autohidesScrollers="YES" horizontalLineScroll="16" horizontalPageScroll="10" verticalLineScroll="16" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qei-nK-1Al">
<scrollView autohidesScrollers="YES" horizontalLineScroll="16" horizontalPageScroll="10" verticalLineScroll="16" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qei-nK-1Al">
<rect key="frame" x="20" y="163" width="108" height="130"/>
<clipView key="contentView" id="kz3-G4-SAs">
<rect key="frame" x="1" y="1" width="106" height="128"/>
<rect key="frame" x="1" y="1" width="106" height="113"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" columnSelection="YES" autosaveColumns="NO" rowHeight="14" id="H3k-dU-KZ9">
<rect key="frame" x="0.0" y="0.0" width="216" height="128"/>
<rect key="frame" x="0.0" y="0.0" width="216" height="113"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -1597,7 +1597,7 @@
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</clipView>
<scroller key="horizontalScroller" verticalHuggingPriority="750" horizontal="YES" id="lhn-Yb-bwG">
<rect key="frame" x="1" y="113" width="106" height="16"/>
<rect key="frame" x="1" y="114" width="106" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="Qxp-g3-yYs">
@ -1626,10 +1626,10 @@
<constraint firstItem="eYy-bt-k7V" firstAttribute="leading" secondItem="qei-nK-1Al" secondAttribute="trailing" constant="13" id="tvy-h2-Sl4"/>
</constraints>
</customView>
<customView misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cdu-gf-7vZ">
<customView translatesAutoresizingMaskIntoConstraints="NO" id="cdu-gf-7vZ">
<rect key="frame" x="531" y="114" width="312" height="196"/>
<subviews>
<scrollView misplaced="YES" autohidesScrollers="YES" horizontalLineScroll="16" horizontalPageScroll="10" verticalLineScroll="16" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Q57-Lg-UOf">
<scrollView autohidesScrollers="YES" horizontalLineScroll="16" horizontalPageScroll="10" verticalLineScroll="16" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Q57-Lg-UOf">
<rect key="frame" x="20" y="46" width="292" height="130"/>
<clipView key="contentView" id="ejs-3E-dQJ">
<rect key="frame" x="1" y="1" width="290" height="128"/>
@ -1676,7 +1676,7 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Joi-iR-nWv">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Joi-iR-nWv">
<rect key="frame" x="268" y="182" width="26" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Live" id="FYE-cJ-eNy">
<font key="font" metaFont="smallSystem"/>