I am trying to read and write the samples from a video file at a specific start point and end point for trimming a video. I am using AVAssetReader and AVAssetWriter.
The logic used here is -
STEP A:
Create asset reader instance with the specified asset.
Set the time range to the reader as per the start and end points. ( Say for example - start point = 5, end point = 15, file length = 55 sec )
Start reading the samples.
Get the sample's exact time stamp with respect to start point that we have passed in.
Store the time stamp of the sample that is accurate with the start point.( could be 5.13 or so ). Say ta = 5.13
Release the reader.
STEP B:
Create a new reader instance with the specified asset.
Set the time range to the reader as per the start and end points. ( Say for example - start point = 5, end point = 15, file length = 55 sec )
Start reading the samples.
Create a new sample buffer with sample timing info altered as
( sample buffer's time stamp t1- ta fetched from STEP A ) - This starts to write from 0
( sample buffer's time stamp t2- ta fetched from STEP A )
( sample buffer's time stamp t3- ta fetched from STEP A ) and so on till end point.
Release the reader.
The code sample for the same is:
STEP A:
while ([assetWriterInput isReadyForMoreMediaData] )
{
CMSampleBufferRef sampleBuffer = [assetReaderOutput copyNextSampleBuffer];
if (sampleBuffer != NULL)
{
CMTime originalTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
float time = CMTimeGetSeconds( originalTime );
// This is where we store the time stamp
fTimeTange = time;
[HelpMethods setCorrectEditTime:fTimeTange]; // This is stored globally
// This is to release the readers and writers and start a fresh call with the stored time stamp ta
[delegate resetTimeRange];
return;
}
}
STEP B:
while ([assetWriterInput isReadyForMoreMediaData] )
{
CMSampleBufferRef sampleBuffer = [assetReaderOutput copyNextSampleBuffer];
if (sampleBuffer != NULL)
{
CMSampleBufferRef finalBuffer = sampleBuffer;
CMSampleBufferRef newSampleBuffer;
CMSampleTimingInfo sampleTimingInfo;
CMTime cmm1 = CMSampleBufferGetOutputDuration(sampleBuffer);
CMTime originalTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
float time = CMTimeGetSeconds( originalTime );
// This is a helper method to get the stored ta at STEP A
fTimeTange = [HelpMethods getCorrectEditTime];
sampleTimingInfo.duration = cmm1;
float milliseconds = (time - fTimeTange) * 600;
NSLog( #"Timestamp in milliseconds = %f", milliseconds );
sampleTimingInfo.presentationTimeStamp = CMTimeMake(milliseconds, 600);
sampleTimingInfo.decodeTimeStamp = kCMTimeInvalid;
CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault,
sampleBuffer,
1,
&sampleTimingInfo,
&newSampleBuffer);
finalBuffer = newSampleBuffer;
BOOL success = YES;
success = [assetWriterInput appendSampleBuffer:finalBuffer];
CFRelease(sampleBuffer);
sampleBuffer = NULL;
}
Since the time stamps of the samples are read in out of order fashion, we end up getting an error saying
"(kFigFormatWriterError_InvalidTimestamp) (decode timestamp is less than previous sample's decode timestamp)"
and the values of time stamps are -
Timestamp in milliseconds = 0.000000
Timestamp in milliseconds = 79.999924
Timestamp in milliseconds = 39.999962
Timestamp in milliseconds = 119.999886
Timestamp in milliseconds = 200.000092
Timestamp in milliseconds = 160.000137
Timestamp in milliseconds = 280.000031
Timestamp in milliseconds = 240.000061
Timestamp in milliseconds = 319.999969
Timestamp in milliseconds = 399.999908
Timestamp in milliseconds = 359.999939
and so on
Any manipulation done to the presentation stamps results in out of order reading of samples.
Looking out a way to overcome this out of order reading of timestamps. Please let know.
Thanks in advance,
Champa
Related
I am trying to get my power bi data from my HRIS platform to calculate hours worked - hours on lunch, to get a total of hours worked in a day.
I have tried grouping, pivots, formulas, and because my HRIS platform send the "check-in" time at the start of a shift and the "check-in" time when they clock back in from lunch, as the same "check-in" classification, I cannot associate it with one or the other, it picks the most recent one, if I say return "check-in" (My data set is intraday and updates every hour so I can get all Clock events for the current day)
I have included an example of what my data looks like right from the HRIS into Power Bi
Sample Data Set
Full Data Sheet Columns
Formula's Used in Order:
Check In =
IF(AND(Merge1[Current Day]=Merge1[Day of the
Week],Merge1[Clock_Event_Type]="Check-in"),
Merge1[Clock_Event_Time_-_No_Time_Zone])
Check Out (Lunch) =
IF(Merge1[Day of the Week]= Merge1[Current Day],
IF(Merge1[Clock_Event_Type]= "Check-out
(meal)",Merge1[Clock_Event_Time_-_No_Time_Zone],BLANK()))
Check in (Lunch) = IF(Merge1[Current Day]=Merge1[Day of the
Week],
VAR checkin = Merge1[Check In]
VAR outlunch = Merge1[Check Out (Lunch)]
VAR timeinfromlunch = IF(checkin>outlunch,checkin)
return timeinfromlunch)
Check Out = IF(Merge1[Day of the Week]= Merge1[Current Day],
IF(Merge1[Clock_Event_Type] = "Check-out",
Merge1[Clock_Event_Time_-_No_Time_Zone]),BLANK())
Current Time = IF(AND(Merge1[Current Day]=Merge1[Day of the
Week],Merge1[Clock_Event_Type]="Check-in"),
NOW()
)
CPH Calc (Intraday Shift) = IF(Merge1[Current Time]<Merge1[Shift
End Today],Merge1[Current Time],Merge1[Check Out])
Hours Worked =
IF(AND(Merge1[Current Day]=Merge1[Day of the
Week],Merge1[Clock_Event_Type]="Check-in"),
VAR totalsecondsinbreak = DATEDIFF(Merge1[Check Out
(Lunch)],Merge1[Check in (Lunch)],SECOND)
VAR total_secondsworking = DATEDIFF(Merge1[Check In],Merge1[CPH
Calc (Intraday Shift)],SECOND)
VAR totalseconds = total_secondsworking-totalsecondsinbreak
VAR DAXHours = (totalseconds/60)/60
RETURN IF(Merge1[Clock_Event_Time_-
_No_Time_Zone]=0,BLANK(),DAXHours))
Shift Start Today = IF(Merge1[Current Day]=Merge1[Day of the
Week],TODAY() + Merge1[Start Shift])
Shift End Today = IF(Merge1[Current Day]=Merge1[Day of the
Week],TODAY() + Merge1[End Shift])
On Queue (Milliseconds) = IF(AND(Merge1[Current Day]=Merge1[Day
of the Week],Merge1[Clock_Event_Type]="Check-in"),
VAR onqueueseconds = RELATED('Table (2)'[On Queue])
VAR milliseconds = onqueueseconds
VAR total_second = milliseconds/1000
VAR minutes = total_second/60
VAR hours_decimal = minutes/60
VAR hours = INT(hours_decimal)
return onqueueseconds)
Utilization =
IF(AND(Merge1[Current Day]=Merge1[Day of the
Week],Merge1[Clock_Event_Type]="Check-in"),
VAR productivetime = Merge1[Hours Productive Time]
VAR workedtime = Merge1[Hours Worked]
VAR Ult = IFERROR(productivetime/workedtime,BLANK())
return Ult
)
Hours Productive Time =
IF(AND(Merge1[Current Day]=Merge1[Day of the
Week],Merge1[Clock_Event_Type]="Check-in"),
VAR milliseconds = Merge1[On Queue (Milliseconds)]
VAR total_second = milliseconds/1000
//VAR minutes = total_second/60
//VAR hours_decimal = minutes/60
//VAR hours = INT(hours_decimal)
VAR DAXHours = (total_second/60)/60
return DAXHours+.5)
The hackerrank challenge is in the following url: https://www.hackerrank.com/challenges/python-time-delta/problem
I got testcase 0 correct, but the website is saying that I have wrong answers for testcase 1 and 2, but in my pycharm, I copied the website expected output and compared with my output and they were exactly the same.
Please have a look at my code.
#!/bin/pyth
# Complete the time_delta function below.
from datetime import datetime
def time_delta(tmp1, tmp2):
dicto = {'Jan':1, 'Feb':2, 'Mar':3,
'Apr':4, 'May':5, 'Jun':6,
'Jul':7, 'Aug':8, 'Sep':9,
'Oct':10, 'Nov':11, 'Dec':12}
# extracting t1 from first timestamp without -xxxx
t1 = datetime(int(tmp1[2]), dicto[tmp1[1]], int(tmp1[0]), int(tmp1[3][:2]),int(tmp1[3][3:5]), int(tmp1[3][6:]))
# extracting t1 from second timestamp without -xxxx
t2 = datetime(int(tmp2[2]), dicto[tmp2[1]], int(tmp2[0]), int(tmp2[3][:2]), int(tmp2[3][3:5]), int(tmp2[3][6:]))
# converting -xxxx of timestamp 1
t1_utc = int(tmp1[4][:3])*3600 + int(tmp1[4][3:])*60
# converting -xxxx of timestamp 2
t2_utc = int(tmp2[4][:3])*3600 + int(tmp2[4][3:])*60
# absolute difference
return abs(int((t1-t2).total_seconds()-(t1_utc-t2_utc)))
if __name__ == '__main__':
# fptr = open(os.environ['OUTPUT_PATH'], 'w')
t = int(input())
for t_itr in range(t):
tmp1 = list(input().split(' '))[1:]
tmp2 = list(input().split(' '))[1:]
delta = time_delta(tmp1, tmp2)
print(delta)
t1_utc = int(tmp1[4][:3])*3600 + int(tmp1[4][3:])*60
For a time zone like +0715, you correctly add “7 hours of seconds” and “15 minutes of seconds”
For a timezone like -0715, you are adding “-7 hours of seconds” and “+15 minutes of seconds”, resulting in -6h45m, instead of -7h15m.
You need to either use the same “sign” for both parts, or apply the sign afterwards.
I would like to know what could be the best way to obtain the starting date values for each month based on the date range.
For example: If I am given a year range of 2015-11-10 and 2018-01-15(format YYYY-mm-dd). Then I would like to extract following dates:
2015-12-01
2016-01-01
.
.
2018-01-01
You can try to use this flow for generating the first day of each month in the provided date range.
Overall flow
Step 1 Configuration: Start
Step 2 Configuration: Configure Date Range
Provide the start and end dates as configuration parameters via this step.
Step 3 Configuration: Generate First Dates For Months
This uses a Groovy script, which is provided below
Groovy script
flowFile = session.get();
if(!flowFile)
return;
DATE_FORMAT = 'yyyy-MM-dd';
startDate = Date.parse(DATE_FORMAT, flowFile.getAttribute("start_date"));
endDate = Date.parse(DATE_FORMAT, flowFile.getAttribute("end_date"));
allFirstDates = "";
Calendar calendar = Calendar.getInstance();
Set firstDaysOfMonths = new LinkedHashSet();
for (int i = 0; i <= endDate-startDate; i++) {
calendar.setTime(startDate.plus(i));
calendar.set(Calendar.DAY_OF_MONTH, 1);
firstDayOfMonth = calendar.getTime();
if (firstDayOfMonth.compareTo(startDate) >= 0) {
firstDaysOfMonths.add(calendar.getTime().format(DATE_FORMAT));
}
}
firstDaysOfMonths.each {
firstDayOfMonth -> allFirstDates = allFirstDates + firstDayOfMonth + "\n";
}
flowFile = session.putAttribute(flowFile,"all_first_dates", allFirstDates );
session.transfer(flowFile,REL_SUCCESS)
Step 4 Configuration: View Result
Output of run:
When the flow is run, the attribute all_first_dates will be populated with the first dates of each month in the date range.
I have a database with the total played game time in seconds. I want to fetch these seconds from the database, add the current session play time in seconds and then update the database.
This should happen every 5 seconds. I have done this, but because I do currentSession + totalTimePlayedDB it keeps adding the full duration of my current session over and over... Any ideas?
local currentPlayTime = player:TimeConnected()
print(math.Round(currentPlayTime))
local playerValues = MySQLite.queryValue([[SELECT time FROM chiz_time WHERE sid=']].. player:SteamID() ..[[']], function(time)
if time == "" then
time = math.Round(currentPlayTime)
else
time = math.Round(time + time - currentPlayTime )
end
MySQLite.query([[UPDATE chiz_time SET time = ']].. time ..[[' WHERE sid=']].. player:SteamID() ..[[']])
end)
I do currentSession + totalTimePlayedDB it keeps adding the full duration of my current
You just need to compute the delta from your last save time.
In your init code somewhere:
lastSaveTime = 0
In your save routine:
totalTimePlayedDB = totalTimePlayedDB + currentSession - lastSaveTime
if (totalTimePlayedDB is written to the database successfully) then
lastSaveTime = currentSession
end
i have a time format like this:
string s = DateTime.Now.ToString();
which gives me output like
11/29/2013 6:26:13PM
Now how can i convert this output into millisecond in windowsPhone???
Updated:
First i want to save the current time when the user launch my app. after that whenever the user launch my app again then i also get the time and compare the current launching time with previously stored time and check whether the time difference becomes "one day" or not.
For this comparison i need to covert 11/29/2013 6:26:13PM this into millisecond.
Another question tell me how can i convert "6:26:13PM" only this into millisecond??
If I understood correctly just do this:
Create a date from your input:
DateTime yourInitialDateTime = DateTime.Parse("11/29/2013 6:26:13PM");
After that
TimeSpan span = DateTime.Now - yourInitialDateTime;
So in span.TotalDays you will have how many days has passed.
Edit
If you have only the time of day and want to know the millisecond of that time you must add a date and subtract it with hour 0:00:00 like this:
string dummyDate = "01/01/0001";
DateTime end = DateTime.Parse(dummyDate + " " + "6:26:13PM");
var milli = end.Subtract(new DateTime()).TotalMilliseconds;
That is it.
Try this.
var ThatDay = DateTime.Now.AddDays(-1); //This is hard coded but you have to get from where you are storing.
var Today = DateTime.Now;
var Diff = (Today - ThatDay).Milliseconds;
var FriendlyDiff = (Today - ThatDay).ToFriendlyDisplay(5);
public static class TimeSpanExtensions
{
private enum TimeSpanElement
{
Millisecond,
Second,
Minute,
Hour,
Day
}
public static string ToFriendlyDisplay(this TimeSpan timeSpan, int maxNrOfElements)
{
maxNrOfElements = Math.Max(Math.Min(maxNrOfElements, 5), 1);
var parts = new[]
{
Tuple.Create(TimeSpanElement.Day, timeSpan.Days),
Tuple.Create(TimeSpanElement.Hour, timeSpan.Hours),
Tuple.Create(TimeSpanElement.Minute, timeSpan.Minutes),
Tuple.Create(TimeSpanElement.Second, timeSpan.Seconds),
Tuple.Create(TimeSpanElement.Millisecond, timeSpan.Milliseconds)
}
.SkipWhile(i => i.Item2 <= 0)
.Take(maxNrOfElements);
return string.Join(", ", parts.Select(p => string.Format("{0} {1}{2}", p.Item2, p.Item1, p.Item2 > 1 ? "s" : string.Empty)));
}
}