How to detect if video is running on Mac? - macos

I want to know the idle time of Mac. Currently I use this code
CFMutableDictionaryRef properties = 0;
CFTypeRef obj;
mach_port_t masterPort;
io_iterator_t iter;
io_registry_entry_t curObj;
IOMasterPort(MACH_PORT_NULL, &masterPort);
/* Get IOHIDSystem */
IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter);
if (iter == 0)
{
return -1;
}
else
{
curObj = IOIteratorNext(iter);
}
if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL)
{
obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime"));
CFRetain(obj);
}
else
{
return -1;
}
uint64_t tHandle = 0;
if (obj)
{
CFTypeID type = CFGetTypeID(obj);
if (type == CFDataGetTypeID())
{
CFDataGetBytes((CFDataRef) obj, CFRangeMake(0, sizeof(tHandle)), (UInt8*) &tHandle);
}
else if (type == CFNumberGetTypeID())
{
CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &tHandle);
}
else
{
// error
tHandle = 0;
}
CFRelease(obj);
tHandle /= 1000000; // return as milliseconds
}
else
{
tHandle = -1;
}
CFRelease((CFTypeRef)properties);
IOObjectRelease(curObj);
IOObjectRelease(iter);
return (double)tHandle;
However, I want the idle time to keep 0 if any video is running.
Is there any code sample or library to check? (include video running on iTunes, VLC, youtube on browser or any other video applications)

I can interpret your question several ways:
How to determine when the screensaver kicks in?
Check the following script (original answer):
#!/bin/bash
systemSleepTimeMinutes=`pmset -g | grep "^[ ]*sleep" | awk '{ print $2 }'`
if [ $systemSleepTimeMinutes -gt "0" ]; then
systemSleepTime=`echo "$systemSleepTimeMinutes * 60" | bc`
devicesIdleTime=`ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print $NF/1000000000; exit}'`
secondsBeforeSleep=`echo "$systemSleepTime - $devicesIdleTime" | bc`
echo "Time before sleep (sec): $secondsBeforeSleep"
exit 0
else
echo "The system is set to not sleep."
exit 0
fi
In case the screensaver is suppressed, for example by VLC, the result is:
The system is set to not sleep.
Otherwise it returns the time until the screensaver kicks in, for example:
Time before sleep (sec): 899.88056
Run the script above through NSTask or NSAppleScript and parse the result.
Please note "sleep" may also rever to the screensaver, depending on which one kicks in first.
How to determine wether the screensaver is suppressed?
The following line does the trick:
pmset -g | grep "^[ ]*sleep" | awk '{ print $2 }'
In case the screensaver is suppressed it returns 0.
Run the line above through NSTask or NSAppleScript and parse the result.
How to suppress the screensaver?
The official Apple documentation (including code snippet):
How can I prevent system sleep while my application is running?
EDIT (Response to comment)
However, is there a built-in method that works the same as this script?
I'm not familiar with such a method. I actually doubt it exists.
Quick NSAppleScript example:
NSString *source = #"do shell script \"pmset -g | grep \\\"^[ ]*sleep\\\" | awk '{ print $2 }'\"";
NSAppleScript *script= [[NSAppleScript alloc] initWithSource:source];
NSDictionary *scriptError = nil;
NSAppleEventDescriptor *descriptor=[script executeAndReturnError:&scriptError];
if(scriptError) {
NSLog(#"Error: %#",scriptError);
} else {
if ([[descriptor stringValue] intValue] == 0) {
NSLog(#"Screensaver suppressed.");
} else {
NSLog(#"Screensaver not suppressed.");
}
}
Just don't be reticent about using NSTask or NSAppleScript :)

Better yet, watch for com.apple.screensaver.didstart and com.apple.screensaver.didstop

Related

Why do I get an error message when I implemented a simple shell command on Linux?

In Linux Ubuntu 20.04.4, I implemented a simple shell command in the "sh.c" file.
Entering
./a.out
and command line by line runs normally.
enter image description here
ls > y
cat < y | sort | uniq | wc > y1
cat y1
rm y1
ls | sort | uniq | wc
rm y
However, if you save the commands to the "t.sh" file
enter image description here
and run them at once like
./a.out < t.sh
an error appears.
enter image description here
print result :
5 5 29
5 5 29
cat: y1: No such file or directory
rm: Cannot erase 'y1': no such file or directory
4 4 27
rm: Cannot clear 'y': no such file or directory
When I checked with the "ls" command, both the cat and rm commands worked well, but I got a error message like that "rm: Cannot erase 'y1': no such file or directory."
What's the problem?
The other person worked normally with the same code...
This is part of the code implemented.
void runcmd(struct cmd *cmd)
{
int p[2], r;
int fd;
int pid;
char str[30] ="/bin/";
FILE * stream;
struct execcmd *ecmd;
struct pipecmd *pcmd;
struct redircmd *rcmd;
if(cmd == 0)
_exit(0);
switch(cmd->type){
default:
fprintf(stderr, "unknown runcmd\n");
_exit(-1);
case ' ':
ecmd = (struct execcmd*)cmd;
if(ecmd->argv[0] == 0){
_exit(0);
fprintf(stderr, "exec not implemented\n");
}
// Your code here ...
else if(execvp(ecmd->argv[0],ecmd->argv)==-1){
ecmd->argv[0] = strcat(str,ecmd->argv[0]);
if(execvp(ecmd->argv[0],ecmd->argv)==-1){
fprintf(stderr,"file not found\n");
exit(1);
}
}
break;
case '>':
rcmd = (struct redircmd*)cmd;
ecmd = (struct execcmd*)(rcmd->cmd);
if(0 <(fd = open(rcmd->file,O_CREAT|O_WRONLY,0644))){
stream = freopen(rcmd->file,"w",stdout);
runcmd(rcmd->cmd);
fclose(stream);
}
else {
fprintf(stderr,"file open error\n");
}
close(fd);
stream = NULL;
break;
case '<':
rcmd = (struct redircmd*)cmd;
// Your code here ...
if( 0 < (fd = open(rcmd->file,rcmd->flags))){
stream = freopen(rcmd->file,"r",stdin);
runcmd(rcmd->cmd);
fclose(stream);
close(fd);
}
else fprintf(stderr,"file open error\n");
break;
case '|':
pcmd = (struct pipecmd*)cmd;
// Your code here ...
struct cmd * lcmd =(pcmd->left);
struct cmd * rcmd =(pcmd->right);
int fd[2];
if(pipe(fd)==-1){
fprintf(stderr,"pipe error");
exit(1);
}
pid = fork1();
if(pid == 0){
dup2(fd[1],1);
close(fd[0]);
runcmd(lcmd);
}
else{
dup2(fd[0],0);
close(fd[1]);
runcmd(rcmd);
}
break;
}
_exit(0);
}
Have you declared #!/bin/sh at top of script

Kaldi librispeech data preparation error

I'm trying to do ASR system. Im using kaldi manual and librispeech corpus.
In data preparation step i get this error
utils/data/get_utt2dur.sh: segments file does not exist so getting durations
from wave files
utils/data/get_utt2dur.sh: could not get utterance lengths from sphere-file
headers, using wav-to-duration
utils/data/get_utt2dur.sh: line 99: wav-to-duration: command not found
And here the piece of code where this error occures
if cat $data/wav.scp | perl -e '
while (<>) { s/\|\s*$/ |/; # make sure final | is preceded by space.
#A = split;
if (!($#A == 5 && $A[1] =~ m/sph2pipe$/ &&
$A[2] eq "-f" && $A[3] eq "wav" && $A[5] eq "|")) { exit (1); }
$utt = $A[0]; $sphere_file = $A[4];
if (!open(F, "<$sphere_file")) { die "Error opening sphere file $sphere_file"; }
$sample_rate = -1; $sample_count = -1;
for ($n = 0; $n <= 30; $n++) {
$line = <F>;
if ($line =~ m/sample_rate -i (\d+)/) { $sample_rate = $1; }
if ($line =~ m/sample_count -i (\d+)/) { $sample_count = $1;
}
if ($line =~ m/end_head/) { break; }
}
close(F);
if ($sample_rate == -1 || $sample_count == -1) {
die "could not parse sphere header from $sphere_file";
}
$duration = $sample_count * 1.0 / $sample_rate;
print "$utt $duration\n";
} ' > $data/utt2dur; then
echo "$0: successfully obtained utterance lengths from sphere-file headers"
else
echo "$0: could not get utterance lengths from sphere-file headers,
using wav-to-duration"
if command -v wav-to-duration >/dev/null; then
echo "$0: wav-to-duration is not on your path"
exit 1;
fi
In file wav.scp i got such lines:
6295-64301-0002 flac -c -d -s /home/tinin/kaldi/egs/librispeech/s5/LibriSpeech/dev-clean/6295/64301/6295-64301-0002.flac |
In this dataset i have only flac files(they downloaded via provided script) and i dont understand why we search wav-files? And how run data preparation correctly(i didnt change source code in this manual.
Also, if you explain to me what is happening in this code, then I will be very grateful to you, because i'm not familiar with bash and perl.
Thank you a lot!
The problem I see from this line
utils/data/get_utt2dur.sh: line 99: wav-to-duration: command not found
is that you have not added the kaldi tools in your path.
Check the file path.sh and see if the directories that it adds to your path are correct (because it has ../../.. inside and it might not match your current folder setup)
As for the perl script, it counts the samples of the sound file and then it divides with the sample rate in order to get the duration. Don't worry about the 'wav' word, your files might be on another format, it's just the name of the kaldi functions.

Out of memory with running JavaScript by PhantomJS

My shell script is written in cygwin for windows:
// main.sh
#!/bin/bash
[ "$#" -lt 1 ] && echo "Usage: thisscript.sh <filename.txt>" && exit 0
filename=`basename -s .txt $1`
i=0
while [ $i == 0 ]
do
phantomjs --web-security=no myXHR.js $filename.txt
logLastLine=`tail -n 1 $filename.log`
if [[ "$logLastLine" =~ "Error" ]]; then
echo "Error occurs, now keep looping it..."
elseif [[ "$logLastLine" =~ "503" ]]; then
echo "Error occurs, now keep looping it..."
elseif [[ "$logLastLine" =~ "500" ]]; then
echo "Error occurs, now keep looping it..."
else
echo "Complete! Exiting the execution..."
i=1
fi
done
And here are the codes contained in the myXHR.js
// myXHR.js
phantom.onError = function(msg, trace) {
console.log("PhantomJS Error");
phantom.exit();
};
var fs = require('fs'), system = require('system');
if (system.args.length < 2) {
console.log("Usage: myXHR.js <FILE>");
}
var content = '',
f = null,
lines = null,
eol = "\n";
try {
f = fs.open(system.args[1], "r");
filename=system.args[1].replace(/\.txt/,"");
content = f.read();
} catch (e) {
console.log(e);
}
if (f) {
f.close();
}
var request = new XMLHttpRequest();
if (content) {
lines = content.split(eol);
for (i=0; i<(lines.length-1);i++) {
request.open('GET', "http://stackoverflow.com/", false);
request.send();
if (request.status === 200) {
try {
fs.write($filename.log, line[i] + "Succeed!", 'a');
} catch(e) {
console.log(e);
}
} else {
try {
fs.write($filename.log, line[i] + "Error!", 'a');
} catch(e) {
console.log(e);
}
}
}
phantom.exit();
To illustrate, the javascript, executed by PhantomJS, are reading 1st argument(a filename.txt file), passed into the shell script, line by line. For each line it sends a XMLHttpRequest to check the request status and writes it into filename.log file.
Error status number includes 503 and 500. Luckily these statuses are less likely to occur again if I resend the same XMLHttpRequest. So what I need to do is to set up a error handler which is for resend the same XMLHttpRequest when errors occur.
In this error handler, I use X=${tail -n 1 log} to see if there is a error status number(containing "503" or "500" string). For instance, if [[ "$X" =~ "503" ]]; then restart the execution of the javascript, by not giving i=1 and while loop never exits. Until it has finished reading the last line of the imported file without any error status numbers.
(I know it is awkward to handle error like this, but it was a quick solution that came to my mind.)
But this is theoretical. In practice, this script ended with an error "Memory exhausted". I reckon this error is triggered by the large amount of lines(>100k) in the $1 file, and it occurs in the JavaScript execution part. I used free -m command to get memory usage information, and I noticed that when Javascript is running, the used swap is increasing!
Could anybody teach me how to release the memory when the scripts is being executed.

Perl script hangs for no reason

So I have this small script which checks two log files for a specific line and compares the lines.
The script is used on several different Windows Bamboo Agents. But on one it just hangs and doesn't exit. Since the script is used in bamboo the whole job hangs, when this script doesn't exit.
When I check the computer via remote access and kill the script the job continues until it reaches the script again.
This is the script, which is started by another script.
#! /usr/bin/perl
my $naluresult = 2;
my $hevcresult = 2;
my $hevcfailed = 0;
use strict;
use warnings;
#---------------------------------------------
#check for $ARGV[0] and $ARGV[1]
open( my $nalulog, "<", $ARGV[1] )
or die "cannot open File:$!\n\n";
while (<$nalulog>) {
chomp;
$_ =~ s/\s+//g;
if ( $_ =~ m/MD5:OK/ ) {
$naluresult = 1;
} else {
if ( $_ =~ m/MD5:MISSING/ ) {
$naluresult = 0;
}
}
}
close $nalulog;
#---------------------------------------------
open( my $hevclog, "<", $ARGV[0] )
or die "cannot open File:$!\n\n";
while (<$hevclog>) {
chomp;
$_ =~ s/\s+//g;
if ( $_ =~ m/MD5check:OK/ ) {
$hevcresult = 1;
last;
} else {
if ( $_ =~ m/MD5check:FAILED/ ) { $hevcfailed = 1; }
}
if ( $hevcfailed == 1 ) {
#do stuff
}
}
close $hevclog;
#---------------------------------------------
if ( $hevcresult == 2 ) {
print("Missing MD5 status in HEVC Output");
exit(-1);
} elsif ( $naluresult == 2 ) {
print("Missing MD5 status in NALU Output");
exit(-2);
} else {
if ( $naluresult == $hevcresult ) { exit(0); }
else {
#different if-statements to print() to log
exit(1);
}
}
#---------------------EOF---------------------
If your files are just normal disk files that aren't being simultaneously written to by other processes, or locked, or anything like that, then there is nothing in the code you have here that should hang. If the files are both reasonable sizes, the code you have here should read through the files and finish.
However, if one of the files is locked, or is immensely large, or if you have other code that can get stuck in an infinite loop, that would explain why your program is hanging.

Perl kill(0, $pid) in Windows always returning 1

I'm trying to make a Perl script that will run a set of other programs in Windows. I need to be able to capture the stdout, stderr, and exit code of the process, and I need to be able to see if a process exceeds it's allotted execution time.
Right now, the pertinent part of my code looks like:
...
$pid = open3($wtr, $stdout, $stderr, $command);
if($time < 0){
waitpid($pid, 0);
$return = $? >> 8;
$death_sig = $? & 127;
$core_dump = $? & 128;
}
else{
# Do timeout stuff, currently not working as planned
print "pid: $pid\n";
my $elapsed = 0;
#THIS LOOP ONLY TERMINATES WHEN $time > $elapsed ...?
while(kill 0, $pid and $time > $elapsed){
Time::HiRes::usleep(1000); # sleep for milliseconds
$elapsed += 1;
$return = $? >> 8;
$death_sig = $? & 127;
$core_dump = $? & 128;
}
if($elapsed >= $time){
$status = "FAIL";
print $log "TIME LIMIT EXCEEDED\n";
}
}
#these lines are needed to grab the stdout and stderr in arrays so
# I may reuse them in multiple logs
if(fileno $stdout){
#stdout = <$stdout>;
}
if(fileno $stderr){
#stderr = <$stderr>;
}
...
Everything is working correctly if $time = -1 (no timeout is needed), but the system thinks that kill 0, $pid is always 1. This makes my loop run for the entirety of the time allowed.
Some extra details just for clarity:
This is being run on Windows.
I know my process does terminate because I have get all the expected output.
Perl version: This is perl, v5.10.1 built for MSWin32-x86-multi-thread
(with 2 registered patches, see perl -V for more detail) Copyright 1987-2009, Larry Wall
Binary build 1007 [291969] provided by ActiveState http://www.ActiveState.com
Built Jan 26 2010 23:15:11
I appreciate your help :D
For that future person who may have a similar issue
I got the code to work, here is the modified code sections:
$pid = open3($wtr, $stdout, $stderr, $command);
close($wtr);
if($time < 0){
waitpid($pid, 0);
}
else{
print "pid: $pid\n";
my $elapsed = 0;
while(waitpid($pid, WNOHANG) <= 0 and $time > $elapsed){
Time::HiRes::usleep(1000); # sleep for milliseconds
$elapsed += 1;
}
if($elapsed >= $time){
$status = "FAIL";
print $log "TIME LIMIT EXCEEDED\n";
}
}
$return = $? >> 8;
$death_sig = $? & 127;
$core_dump = $? & 128;
if(fileno $stdout){
#stdout = <$stdout>;
}
if(fileno $stderr){
#stderr = <$stderr>;
}
close($stdout);
close($stderr);
Instead of kill 0, use waitpid $pid, WNOHANG:
use POSIX qw( WHOHANG );
if (waitpid($pid, WNOHANG) > 0) {
# Process has ended. $? is set.
...
}

Resources