diff --git a/simple_live_transcode.c b/simple_live_transcode.c
index e11eae69ad08b78233c9584f26b5dd06010d6502..d9829807d2bd6833cbac64f84e00eb87b496e7bf 100644
--- a/simple_live_transcode.c
+++ b/simple_live_transcode.c
@@ -17,7 +17,7 @@ static void copy_to_log(int fd)
 
 int main(int argc, char *argv[])
 {
-	int ret, errpipe[2] = {-1, -1};
+	int ret, canceled = 0, errpipe[2] = {-1, -1};
 	char *src, *dest;
 	pid_t pid;
 	struct pollfd fds = {.fd = -1, .events = POLLIN};
@@ -48,7 +48,9 @@ int main(int argc, char *argv[])
 
 	while (1)
 	{
-		ping_job(jobid, "running", "{\"log\": \"%s\"}", jescape(get_avlogbuf()));
+		canceled = ping_job(jobid, "running", "{\"log\": \"%s\"}", jescape(get_avlogbuf()));
+		if (canceled)
+			kill(pid, SIGINT); /* Stop ffmpeg */
 		poll(&fds, 1, 15000);
 		if (fds.revents & POLLIN)
 			copy_to_log(fds.fd);
@@ -57,7 +59,7 @@ int main(int argc, char *argv[])
 	}
 
 	waitpid(pid, &ret, 0);
-	if (!WEXITSTATUS(ret))
+	if (canceled && (WEXITSTATUS(ret) == 255 || (WIFSIGNALED(ret) && WTERMSIG(ret) == SIGINT)))
 		ping_job(jobid, "finished", "{\"log\": \"%s\"}", jescape(get_avlogbuf()));
 	else if (WIFSIGNALED(ret))
 		job_failed("Subprocesses was killed by signal %s (%i)", strsignal(WTERMSIG(ret)), WTERMSIG(ret));
diff --git a/transcode.c b/transcode.c
index 07143a31c6ae75a755f25abf160337742ccac987..cab1da5e5d5a87ee5e1dc99c7ebe788836d27d7d 100644
--- a/transcode.c
+++ b/transcode.c
@@ -247,7 +247,7 @@ void connect_pads(AVFilterInOut **ins, AVFilterInOut **outs)
 
 int main(int argc, char *argv[])
 {
-	int err, i, progress, _progress;
+	int err, i, progress, _progress, canceled;
 	char *p, *input, *output, *inpath, *outpath, *tmppath, *oldsrcpath;
 	AVFormatContext *demux, *mux;
 	AVCodecContext **decs, **encs;
@@ -329,14 +329,16 @@ int main(int argc, char *argv[])
 	progress = 0;
 
 	ping_job(jobid, "running", 0);
-	while (!av_read_frame(demux, &pkt))
+	while (!canceled && !av_read_frame(demux, &pkt))
 	{
 		i = pkt.stream_index;
 		_progress = av_rescale_q(pkt.pts, demux->streams[i]->time_base, AV_TIME_BASE_Q)*100/demux->duration;
 		if (_progress > progress || !checktime(30))
 		{
-			ping_job(jobid, "running", "{\"progress\": %i, \"log\": \"%s\"}", _progress,
+			canceled = ping_job(jobid, "running", "{\"progress\": %i, \"log\": \"%s\"}", _progress,
 					jescape(get_avlogbuf()));
+			if (canceled)
+				job_failed("Job canceled");
 			progress = _progress;
 		}
 		filtergraph_send(srcs[i], decs[i], &pkt);
diff --git a/util/api.c b/util/api.c
index fec682054cd8f1148c02a757278744adc68845ba..8ce001444817a5a567c9176e7786646b03b69efb 100644
--- a/util/api.c
+++ b/util/api.c
@@ -15,6 +15,7 @@ static size_t curl_write_cb(char *ptr, size_t size, size_t nmemb, void *user)
 int ping_job(int id, char *state, char *status, ...)
 {
 	int ret;
+	long http_status;
 	CURL *curl;
 	va_list ap;
 	char *p, *url, *e_host, *e_status, *e_apikey, *e_state;
@@ -48,6 +49,7 @@ int ping_job(int id, char *state, char *status, ...)
 	curl_easy_setopt(curl, CURLOPT_URL, url);
 	ret = curl_easy_perform(curl);
 	free(p);
+	curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status);
 	curl_easy_cleanup(curl);
 	if (ret)
 	{
@@ -56,5 +58,7 @@ int ping_job(int id, char *state, char *status, ...)
 		return -1;
 	}
 	free(url);
+	if (http_status == 205)
+		return 1; /* Job canceled */
 	return 0;
 }