Xamarin - Video Cropping for iOS - c#

I was wondering if there was a way to crop videos in Xamarin. I can't seem to find any examples. I tried looking at the existing functions and Classes but I couldn't find anything.
Basically make square videos like what Vine and Instagram have. I think this is done by cropping out the rest of the video and not just zooming in.

I find part of the code from one source, I tried to add owner but I could not find. The solution's key part is added by me for cropping which is "VideoCleanAperture" inside AVVideoSettingsCompressed.
videoUrl = ((AVFoundation.AVUrlAsset)avAsset).Url;
NSError assetReaderError;
var assetReader = AVAssetReader.FromAsset(avAsset, out assetReaderError);
var assetTrack = avAsset.Tracks.First();
//Height = (System.nint?)avAsset.NaturalSize.Height,
//Width = (System.nint?)avAsset.NaturalSize.Width,
var inputSettings = new AVVideoSettingsUncompressed()
{
Height = (System.nint?)avAsset.NaturalSize.Height,
Width = (System.nint?)avAsset.NaturalSize.Width,
};
var assetReaderOutput = new AVAssetReaderTrackOutput(assetTrack, settings: inputSettings);
assetReaderOutput.AlwaysCopiesSampleData = false;
string tempFile = Path.Combine(Path.GetTempPath(), "CroppedVideo.mp4");
if (File.Exists(tempFile)) File.Delete(tempFile);
var url = NSUrl.FromFilename(tempFile);
NSError assetWriterError;
var assetWriter = new AVAssetWriter(url, AVFileType.Mpeg4, out assetWriterError);
var outputSettings = new AVVideoSettingsCompressed()
{
Height = 300,
Width = 300,
Codec = AVVideoCodec.H264,
CodecSettings = new AVVideoCodecSettings()
{
AverageBitRate = 1000000,
VideoCleanAperture = new AVVideoCleanApertureSettings(
new NSDictionary(
AVVideo.CleanApertureWidthKey, new NSNumber(300),
AVVideo.CleanApertureHeightKey, new NSNumber(300),
AVVideo.CleanApertureVerticalOffsetKey, new NSNumber(10),
AVVideo.CleanApertureHorizontalOffsetKey, new NSNumber(10)
)
)
},
ScalingMode = AVVideoScalingMode.ResizeAspectFill
};
var assetWriterInput = new AVAssetWriterInput(mediaType: AVMediaType.Video, outputSettings: outputSettings);
assetWriterInput.ExpectsMediaDataInRealTime = false;
assetWriter.AddInput(assetWriterInput);
assetWriter.StartWriting();
assetReader.AddOutput(assetReaderOutput);
assetReader.StartReading();
assetWriter.StartSessionAtSourceTime(CoreMedia.CMTime.Zero);
var mediaInputQueue = new DispatchQueue("mediaInputQueue");
assetWriterInput.RequestMediaData(mediaInputQueue, () =>
{
while (assetWriterInput.ReadyForMoreMediaData)
{
var nextBuffer = assetReaderOutput.CopyNextSampleBuffer();
if (nextBuffer != null)
{
assetWriterInput.AppendSampleBuffer(nextBuffer);
}
else
{
assetWriterInput.MarkAsFinished();
assetWriter.FinishWritingAsync();
assetReader.CancelReading();
assetReader.Dispose();
assetReaderOutput.Dispose();
assetWriter.Dispose();
assetWriterInput.Dispose();
break;
}
}
});
}

Related

Xamarin AVFoundation, add subtitles to a video

I'm trying to add subtitles to a video. But no video cannot be played. Here is my code;
AVPlayer avp;
AVPlayerViewController avpvc;
AVMutableComposition videoPlusSubtitles;
var subtitleEn = "SOME_VTT";
var videoURL = "SOME_MP4_URL";
var url = NSUrl.FromString(videoURL);
var nsVideoUrl = new NSUrl(videoURL);
var localVideoAsset = new AVUrlAsset(nsVideoUrl);
videoPlusSubtitles = new AVMutableComposition();
var videoTrack = videoPlusSubtitles.AddMutableTrack(AVMediaType.Video, 0);
NSError error = new NSError();
videoTrack.InsertTimeRange(CoreMedia.CMTimeRange.Zero, videoPlusSubtitles.TracksWithMediaType(AVMediaType.Video)[0], localVideoAsset.Duration, out error);
var subtitle1 = new NSUrl(subtitleEn);
var subtitleAsset = new AVUrlAsset(subtitle1);
var subttileTrack = videoPlusSubtitles.AddMutableTrack(AVMediaType.Text, 0);
subttileTrack.InsertTimeRange(CoreMedia.CMTimeRange.Zero, videoPlusSubtitles.TracksWithMediaType(AVMediaType.Text)[0], subtitleAsset.Duration, out error);
var playerItems = new AVPlayerItem(videoPlusSubtitles);
avpvc = new AVPlayerViewController();
avp = new AVPlayer(playerItems);
avpvc.Player = avp;
AddChildViewController(avpvc);
View.AddSubview(avpvc.View);
avpvc.View.Frame = View.Frame;
avpvc.ShowsPlaybackControls = true;
avp.Play();
When I type avp = new AVPlayer(url); instead of avp = new AVPlayer(playerItems); everything works fine, so no problems with the video. Any ideas?
This is working for me:
AVMutableComposition videoWithSubtitlesComposition = new AVMutableComposition();
AVMutableCompositionTrack videoTrack = videoWithSubtitlesComposition.AddMutableTrack(AVMediaType.Video, 0);
AVMutableCompositionTrack audioTrack = videoWithSubtitlesComposition.AddMutableTrack(AVMediaType.Audio, 0);
AVMutableCompositionTrack subtitlesTrack = videoWithSubtitlesComposition.AddMutableTrack(AVMediaType.Text, 0);
videoTrack.InsertTimeRange(
new CoreMedia.CMTimeRange { Start = CoreMedia.CMTime.Zero, Duration = videoAsset.Duration },
videoAsset.GetTracks(AVMediaTypes.Video)[0],
CoreMedia.CMTime.Zero, out _
);
audioTrack.InsertTimeRange(
new CoreMedia.CMTimeRange { Start = CoreMedia.CMTime.Zero, Duration = videoAsset.Duration },
videoAsset.GetTracks(AVMediaTypes.Audio)[0],
CoreMedia.CMTime.Zero, out _
);
subtitlesTrack.InsertTimeRange(
new CoreMedia.CMTimeRange { Start = CoreMedia.CMTime.Zero, Duration = subtitlesAsset.Duration },
subtitlesAsset.GetTracks(AVMediaTypes.Text)[0],
CoreMedia.CMTime.Zero, out _
);
In my case, I receive the audio and video track from an url that downloads an mp4 file and another url that downloads a vtt file. They correspond to the videoAsset and subtitlesAsset, respectively.
AVMediaType enum has "Subtitles" but using that instead of "Text" it does not work. Perhaps is a iOS bug.

NoTextEdit ShapeLock is not working - OpenXML SDK

I am trying to make a TextBox locked by using OpenXML SDK. I've tried this method but the TextBox NoTextEdit is not working.
public DocumentFormat.OpenXml.Presentation.Shape GenerateShape(string StrText)
{
DocumentFormat.OpenXml.Presentation.Shape shape1 = new DocumentFormat.OpenXml.Presentation.Shape();
DocumentFormat.OpenXml.Presentation.NonVisualShapeProperties nonVisualShapeProperties1 = new DocumentFormat.OpenXml.Presentation.NonVisualShapeProperties();
DocumentFormat.OpenXml.Presentation.NonVisualDrawingProperties nonVisualDrawingProperties1 = new DocumentFormat.OpenXml.Presentation.NonVisualDrawingProperties() { Id = (UInt32Value)3U, Name = "ID",Hidden=true ,Description="Do not Remove" ,MCAttributes=null };
DocumentFormat.OpenXml.Presentation.NonVisualShapeDrawingProperties nonVisualShapeDrawingProperties1 = new DocumentFormat.OpenXml.Presentation.NonVisualShapeDrawingProperties();
Drawing.ShapeLocks shapeLocks1 = new Drawing.ShapeLocks() { NoTextEdit = true, NoGrouping = true,NoMove=true,NoSelection=true,NoEditPoints=true ,NoAdjustHandles=true ,NoRotation=true,NoChangeArrowheads=true,NoChangeAspect=true,NoChangeShapeType=true,NoResize=true};
nonVisualShapeDrawingProperties1.Append(shapeLocks1);
ApplicationNonVisualDrawingProperties applicationNonVisualDrawingProperties1 = new ApplicationNonVisualDrawingProperties();
PlaceholderShape placeholderShape1 = new PlaceholderShape() { Type = PlaceholderValues.SubTitle, Index = (UInt32Value)1U };
applicationNonVisualDrawingProperties1.Append(placeholderShape1);
nonVisualShapeProperties1.Append(nonVisualDrawingProperties1);
nonVisualShapeProperties1.Append(nonVisualShapeDrawingProperties1);
nonVisualShapeProperties1.Append(applicationNonVisualDrawingProperties1);
DocumentFormat.OpenXml.Presentation.ShapeProperties shapeProperties1 = new DocumentFormat.OpenXml.Presentation.ShapeProperties();
DocumentFormat.OpenXml.Presentation.TextBody textBody1 = new DocumentFormat.OpenXml.Presentation.TextBody();
Drawing.BodyProperties bodyProperties1 = new Drawing.BodyProperties();
Drawing.ListStyle listStyle1 = new Drawing.ListStyle();
Drawing.TextShape shp = new Drawing.TextShape();
Drawing.Paragraph paragraph1 = new Drawing.Paragraph();
Drawing.EndParagraphRunProperties endParagraphRunProperties1 = new Drawing.EndParagraphRunProperties() { Language = "en-US" ,Dirty=false };
paragraph1.Append(GenerateRun(StrText));
paragraph1.Append(endParagraphRunProperties1);
textBody1.Append(bodyProperties1);
textBody1.Append(listStyle1);
textBody1.Append(paragraph1);
shape1.Append(nonVisualShapeProperties1);
shape1.Append(shapeProperties1);
shape1.Append(textBody1);
return shape1;
}
public Drawing.Run GenerateRun(string StrText)
{
Drawing.Run run1 = new Drawing.Run();
Drawing.RunProperties runProperties1 = new Drawing.RunProperties() { Language = "en-US", Dirty = false };
runProperties1.SetAttribute(new OpenXmlAttribute("", "smtClean", "", "0"));
Drawing.Text text1 = new Drawing.Text();
text1.Text = StrText;
Drawing.SolidFill solidFill2 = new Drawing.SolidFill();
Drawing.SchemeColor schemeColor = new Drawing.SchemeColor();
string y = System.Drawing.Color.Transparent.ToArgb().ToString("X");
Drawing.RgbColorModelHex rgbColorModelHex2 = new Drawing.RgbColorModelHex() { Val = "FFFFFF" };//Set Font-Color to Blue (Hex "0070C0").
solidFill2.Append(rgbColorModelHex2);
runProperties1.Append(solidFill2);
Color color = new Color() { Val = "365F91", ThemeColor = ThemeColorValues.Accent1, ThemeShade = "BF" };
run1.Append(runProperties1);
run1.Append(text1);
return run1;
}
Everything works fine except editing. Still the user can edit the TextBox values by double clicking it. How can I avoid this ?
Is there any permanent solution to prevent editing ? Please help me to find a better solution.
Thanks in advance
By researching and communications with the MVP team I've pointed out that there is no way to Protect the TextBox from editing.
As Cindy Meister mentioned in the comments,
Are you able to do it in the PowerPoint application user interface? If not, then Open XML cannot do it... If yes, you can.
If you do not want to text to be changed , Just change it as image then lock that by using NoSelection=true/1 and NoMove=true/1 properties. If you enable these properties the user can't either delete nor change it's position.
For your ref: https://answers.microsoft.com/en-us/msoffice/forum/msoffice_powerpoint-mso_windows8-mso_2016/shape-lock-is-not-working/c1705b55-d2aa-4adb-b538-574ed2fc8eca?tm=1579265435636&page=1&rtAction=1579495439869

How do I use AWS SDK for .Net to create an image to an instance I have? (AMI)

I have an Amazon EC2 instance and I need to be able to create an AMI (image) from it programmatically. I'm trying the following:
CreateImageRequest rq = new CreateImageRequest();
rq.InstanceId = myInstanceID;
rq.Name = instance.KeyName;
rq.Description = "stam";
rq.NoReboot = true;
IAmazonEC2 ec2;
AmazonEC2Config ec2conf = new AmazonEC2Config();
ec2 = AWSClientFactory.CreateAmazonEC2Client(ec2conf);
// CreateImageResponse imageResp;
Amazon.EC2.Model.CreateImageResponse imageResp = null;
try
{
imageResp = ec2.CreateImage(rq);
}
catch (AmazonServiceException ase)
{
MessageBox.Show(ase.Message);
}
The result is always an AmazonServiceException saying that there is a NameResolutionFailure.
How do I overcome this? I tried different possible "name" possibilities but cannot find the right one.
string amiID = ConfigurationManager.AppSettings[AmazonConstants.AwsImageId];
string keyPairName = ConfigurationManager.AppSettings[AmazonConstants.AwsKeyPair];
List<string> groups = new List<string>() { ConfigurationManager.AppSettings[AmazonConstants.AwsSecurityGroupId] };
var launchRequest = new RunInstancesRequest()
{
ImageId = amiID,
InstanceType = ConfigurationManager.AppSettings[AmazonConstants.AwsInstanceType],
MinCount = 1,
MaxCount = 1,
KeyName = keyPairName,
SecurityGroupIds = groups,
SubnetId = ConfigurationManager.AppSettings[AmazonConstants.AwsSubnetId]
};
RunInstancesResponse runInstancesResponse = amazonEc2client.RunInstances(launchRequest);
RunInstancesResult runInstancesResult = runInstancesResponse.RunInstancesResult;
Reservation reservation = runInstancesResult.Reservation;
Problem eventually solved!
it turned out thyat some codelines were doing things which were already done already and removing this part:
IAmazonEC2 ec2;
AmazonEC2Config ec2conf = new AmazonEC2Config();
ec2 = AWSClientFactory.CreateAmazonEC2Client(ec2conf);
// CreateImageResponse imageResp;
Amazon.EC2.Model.CreateImageResponse imageResp = null;
Made things clearer and no wrong repetitions happened! Now it works!

Creating a source to destination map view for windows phone

I have a default geocoordinate. Another geocoorinate which the user will provide. I want to change the change the map view such such that the source and destination can be clearly seen on the phone window with max zoom possible. Please help on how to approach this problem. I tried using setview() but i coudn't find an overload which could do the task.
public async void ShowMyLocationOnTheMap(string mapvariable)
{
JObject o = JObject.Parse(mapvariable);
string successcallback = o["successCallback"].ToString();
string failutecallback = o["failureCallback"].ToString();
var markerifo = o["markerInfo"];
int count = markerifo.Count();
try
{
for (int i = 0; i < count; i++)
{
drawmap(markerifo[i],"red");
}
Geolocator myGeolocator = new Geolocator();
Geoposition myGeoposition = await myGeolocator.GetGeopositionAsync();
JObject current = new JObject();
current["locationLatitude"] = myGeoposition.Coordinate.Latitude.ToString();
current["locationLongitude"] = myGeoposition.Coordinate.Longitude.ToString();
current["locationDescription"] = "Your Current Location";
current["locationName"] = "";
drawmap(current,"blue");
GeoCoordinate myGeoCoordinate = new GeoCoordinate(myGeoposition.Coordinate.Latitude, myGeoposition.Coordinate.Longitude);
MapAppzillon.SetView(myGeoCoordinate1,6);
gobject.ContentPanel.Children.Add(MapAppzillon);
var jsonstring = "{\"successMessage\":\" Map Displayed \"}";
string[] param = { successcallback, jsonstring };
gobject.invokeScript("StringToJsonObject", param);
}
catch (Exception ex)
{
var jsonstring = "{\"errorCode\":\"APZ-CNT-107\"}";
string[] param = { failutecallback, jsonstring };
gobject.invokeScript("StringToJsonObject", param);
}
}
public void drawmap(JToken markerifo,string color)
{
double latitude = Convert.ToDouble(markerifo["locationLatitude"].ToString());
double longitude = Convert.ToDouble(markerifo["locationLongitude"].ToString());
myGeoCoordinate1 = new GeoCoordinate(latitude, longitude);
Ellipse myCircle = new Ellipse();
if (color == "red")
{
myCircle.Fill = new SolidColorBrush(Colors.Red);
}
else
myCircle.Fill = new SolidColorBrush(Colors.Blue);
myCircle.Height = 20;
myCircle.Width = 20;
myCircle.Opacity = 50;
myCircle.Tap += (sender, e) => myCircle_Tap(sender, markerifo["locationDescription"].ToString(), markerifo["locationName"].ToString());
// myCircle.Tap += myCircle_Tap;
MapOverlay myLocationOverlay = new MapOverlay();
myLocationOverlay.Content = myCircle;
myLocationOverlay.PositionOrigin = new System.Windows.Point(0.5, 0.5);
myLocationOverlay.GeoCoordinate = myGeoCoordinate1;
MapLayer myLocationLayer = new MapLayer();
myLocationLayer.Add(myLocationOverlay);
MapAppzillon.Layers.Add(myLocationLayer);
}
Edit: I tried using dispatcher.Invoke and it finally worked. but now its loading only once . when i press the back button and specify another geocoordinate setview dosent work. Is there any solution to this.
List<GeoCoordinate> the2Points = new List<GeoCoordinate>();
the2Points.Add(myGeoCoordinate1);
the2Points.Add(myGeoCoordinate);
rect = LocationRectangle.CreateBoundingRectangle(the2Points);
gobject.ContentPanel.Children.Add(MapAppzillon);
MapAppzillon.Dispatcher.BeginInvoke(() =>
{
MapAppzillon.SetView(rect);
});
await Task.Delay(150);
You do need to use the SetView method on the Map control. But it needs a BoundingRectangle to work!
So a quick code snippet:
List<GeoCoordinate> the2Points = new List<GeoCoordinate>();
the2Points.Add(point1);
the2Points.Add(point2);
LocationRectangle rect = LocationRectangle.CreateBoundingRectangle(the2Points);
TheMapControl.SetView(rect);

How to use MonoTouch.Dialog's ActivityElement?

I might be missing something here, but this code:
this.oSectionDRs = new Section()
{
new ActivityElement()
{
Caption = Locale.GetLocale("Settings_Loading"),
Animating = true
}
};
// To begin with just show a loading indicator.
this.Root = new RootElement (Locale.GetLocale("Settings_Select"))
{
this.oSectionDRs
};
Does not show any animated thingy. It is showing the label only. How can I get the animated star?
Using this code:
var root = new RootElement("foo");
root.Add (new Section("foo", "bar") {
new ActivityElement()
{
Caption = "foo",
Animating = true
}
});
var dvc = new DialogViewController(root, false);
window.RootViewController = dvc;
I get both the caption and the activity scroller thing. Not sure it helps you tho! I was just using the built in MT.D.

Categories