Golang with ffmpeg dynamic video Encode - file

Am trying to encode the videos with Golang ffmpeg. Am not able to get the video file, it shows this error
invalid character '-' in numeric literal
Postman:
This is my code:
package main
import (
"encoding/json"
"fmt"
"net/http"
"github.com/gorilla/mux"
"github.com/xfrr/goffmpeg/transcoder"
)
type Encode struct {
Video string `json:"video"`
}
func encodeFfmpeg(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Println("Encodeing Started")
var encode Encode
video := json.NewDecoder(r.Body).Decode(encode)
file, err := os.Open(video)
if err != nil {
log.Fatalln(err)
}
defer file.Close()
buf, err := ioutil.ReadAll(file)
if err != nil {
log.Fatalln(err)
}
cmd := exec.Command("ffmpeg",
"-i", "pipe:0", // take stdin as input
"-c:a", "libmp3lame", // use mp3 lame codec
"-f", "avi",
"pipe:1",
)
resultBuffer := bytes.NewBuffer(make([]byte, 5*1024*1024)) // pre allocate 5MiB buffer
cmd.Stderr = os.Stderr // bind log stream to stderr
cmd.Stdout = resultBuffer // stdout result will be written here
stdin, err := cmd.StdinPipe() // Open stdin pipe
if err != nil {
log.Fatalln(err)
}
err = cmd.Start() // Start a process on another goroutine
if err != nil {
log.Fatalln(err)
}
_, err = stdin.Write(buf) // pump audio data to stdin pipe
if err != nil {
log.Fatalln(err)
}
err = stdin.Close() // close the stdin, or ffmpeg will wait forever
if err != nil {
log.Fatalln(err)
}
err = cmd.Wait() // wait until ffmpeg finish
if err != nil {
log.Fatalln(err)
}
outputFile, err := os.Create(encodeFile) // create new file
if err != nil {
log.Fatalln(err)
}
defer outputFile.Close()
_, err = outputFile.Write(resultBuffer.Bytes()) // write result buffer to file
if err != nil {
log.Fatalln(err)
}
json.NewEncoder(w).Encode(map[string]interface{}{
"status": "success",
"statusCode": 200,
"data": "Successfully Encoded file",
})
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/encode", encodeFfmpeg).Methods("POST")
//router.HandleFunc("/rtsp", rtsp).Methods("POST")
// config port
fmt.Printf("Starting server at 8080 \n")
http.ListenAndServe(":8080", router)
}
video.mp4 file not showing in request body. Please help me to solve this issue

json.NewDecoder(r.Body).Decode(encode) returns error not video and another thing is that you send your data in form so you can access file from form like:
file, header, err := r.FormFile("video")

Related

How to print a file or formatet text on a network printer with golang

The below code should print some formatted text on a labeled printer in the network.
I have created a PDF which I would send to the printer but I get only errors- "wrong medium..."
Note: The printer printed fine with standard font/standard size text, but I should be able to print formatted text as well.
Simple text is working on a Brother QL-500. But I get only errors on the printer and not in the code if i send the pdf content. Raw settings don't work either.
Does someone have a solution and example code?
Libraries:
PDF - github.com/jung-kurt/gofpdf
Printer - github.com/alexbrainman/printer
Sample Code:
package main
import (
"bytes"
"flag"
"fmt"
"log"
"runtime"
"time"
prt "github.com/alexbrainman/printer"
"github.com/jung-kurt/gofpdf"
)
func main() {
log.SetFlags(log.LstdFlags | log.Llongfile)
printFormat := flag.String("format", "pdf", "print the pdf content")
savePDF := flag.Bool("s", false, "save pdf only")
flag.Parse()
// pdf output
if *savePDF {
// create pdf
pdf := newReport()
// Save pdf to disc
pdf.OutputFileAndClose("report.pdf")
} else {
var buf []byte
var datatype string
// switch between formats
switch *printFormat {
case "text":
buf = []byte("Text report")
datatype = "text"
case "pdf":
// create pdf
pdf := newReport()
var b bytes.Buffer
err := pdf.Output(&b)
if err != nil {
fmt.Println(err)
}
buf = b.Bytes()
datatype = "raw"
}
// send content to printer
fmt.Println(string(buf))
printContent(datatype, buf)
}
}
func newReport() *gofpdf.Fpdf {
pdf := gofpdf.NewCustom(&gofpdf.InitType{
UnitStr: "mm",
Size: gofpdf.SizeType{Wd: 62, Ht: 90},
OrientationStr: "P",
})
// Pagebreak
pdf.SetAutoPageBreak(false, 0)
// Fileinformations
pdf.SetTitle("Test PDF", true)
// Page Margin
pdf.SetMargins(1, 1, 1)
// We start by adding a new page to the document.
pdf.AddPage()
// UTF8 from File
trans := pdf.UnicodeTranslatorFromDescriptor("")
// Title
pdf.SetFont("Arial", "B", 6)
pdf.CellFormat(0, 2, trans("Test PDF"), "", 0, "C", false, 0, "")
// The `Ln()` function moves the current position to a new line, with
// an optional line height parameter.
pdf.Ln(-1)
pdf.SetFont("Arial", "", 5)
pdf.CellFormat(0, 2, time.Now().Format("02.01.2006 15:04"), "", 0, "C", false, 0, "")
pdf.Ln(-1)
pdf.SetFont("Arial", "B", 5)
pdf.CellFormat(0, 2, trans("new text in pdf"), "", 0, "C", false, 0, "")
pdf.Ln(3)
return pdf
}
func printContent(datatype string, content []byte) {
if runtime.GOOS == "windows" {
name, err := prt.Default() // returns name of Default Printer as string
if err != nil {
fmt.Println(err)
}
fmt.Println(name)
p, err := prt.Open(name) // Opens the named printer and returns a *Printer
if err != nil {
fmt.Println(err)
}
err = p.StartDocument("test", datatype)
if err != nil {
fmt.Println(err)
}
err = p.StartPage() // begin a new page
if err != nil {
fmt.Println(err)
}
n, err := p.Write(content) // Send some text to the printer
if err != nil {
fmt.Println(err)
}
fmt.Println("Num of bytes written to printer:", n)
err = p.EndPage() // end of page
if err != nil {
fmt.Println(err)
}
err = p.EndDocument() // end of document
if err != nil {
fmt.Println(err)
}
err = p.Close() // close the resource
if err != nil {
fmt.Println(err)
}
}
}
Usage:
Save pdf only
go run main.go -s
Send text to printer
go run main.go -format=text
Send pdf content to printer
go run main.go -format=pdf
The printing library you are using doesn't appear to support PDFs.
https://github.com/alexbrainman/printer/issues/6
I'm in the same bucket trying to find a way to print PDFs in Go. I am currently experimenting with https://github.com/jadefox10200/goprint

Go - Download file from URL with Sequence

i am trying to learn some new stuff with GoLang, and got a litlebit stuck, probaly the reason is just that i am not very good at using arrays.
So heres what i want to do:
Make variable.
Download with that variable.
Add ++1 for that variable
Download with added 1
and loop it lets say 10 times.
I am all good with points 1 and two, but little stuck with 3 & 4. :).
all the files come in .pdf, thats why i made that strconv there.
I probaly should make somekind of Loop in main, and call DownloadFile function with some array parameters in there?
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
)
func main() {
url_id := strconv.Itoa(23430815+2)
filename := url_id+".pdf"
fileUrl := "https://someurLid="+url_id
if err := DownloadFile(filename, fileUrl); err != nil {
panic(err)
}
fmt.Println(fileUrl)
}
func DownloadFile(filepath string, url string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
return err
}
try this.
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
)
func main() {
url_id_num := 23430815+2
for i := 0; i < 10; i++ {
url_id := strconv.Itoa(url_id_num+i)
filename := url_id+".pdf"
fileUrl := "https://someurLid="+url_id
if err := DownloadFile(filename, fileUrl); err != nil {
panic(err)
}
fmt.Println(fileUrl)
}
}
func DownloadFile(filepath string, url string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
return err
}
Cerise Limón gave the answer and thats thats how it worked out.
arr := make([]uint8, 3) //How many times it loops
url_id := 23430815 //Starting from id, filename
for range arr {
filename := strconv.Itoa(url_id)+".pdf"
fileUrl := "https://someurl?id="+strconv.Itoa(url_id)
if err := DownloadFile(filename, fileUrl); err != nil {
panic(err)
}
fmt.Println(fileUrl)
url_id++
}
Thank you for pointing out where i should start! :).

Golang : Byte insert into [ ] byte

I'm working on GRPC stream, In server side, I receive the multiple byte inside the for loop, I want to merge in a single array of byte (I tried append method but not use), Here I have attached my sample code. Any one guide me.
Example code
func (s *ServerGRPC) Upload(stream pb.GuploadService_UploadServer) (err error) {
for {
resp, err := stream.Recv()
if err != nil {
if err == io.EOF {
goto END
}
err = errors.Wrapf(err,
"failed unexpectadely while reading chunks from stream")
return err
}
for _, result := range resp.Content {
fmt.Println("result ====>>>", result)
//Actual Output
//result ====>>> 136
//result ====>>> 84
//result ====>>> 232
//result ====>>> 12
//Expectation
//result ===> [136 84 232 12]
}
}
s.logger.Info().Msg("upload received")
END:
err = stream.SendAndClose(&pb.UploadStatus{
Message: "Upload received with success",
Code: pb.UploadStatusCode_Ok,
})
if err != nil {
err = errors.Wrapf(err,
"failed to send status code")
return
}
return
}
You are appending to Sample but printing req.Content
There is nothing wrong with merging slices. if just have to print Sample to see merged result.
func (s *ServerGRPC) Upload(stream pb.GuploadService_UploadServer) (err error) {
var respBytes []byte
for {
resp, err := stream.Recv()
if err != nil {
if err == io.EOF {
goto END // you can use break here
}
err = errors.Wrapf(err,
"failed unexpectadely while reading chunks from stream")
return err
}
for _, result := range resp.Content {
fmt.Println("result ====>>>", result)
respBytes = append(respBytes, result)
}
}
s.logger.Info().Msg("upload received")
// print respBytes here
END:
err = stream.SendAndClose(&pb.UploadStatus{
Message: "Upload received with success",
Code: pb.UploadStatusCode_Ok,
})
if err != nil {
err = errors.Wrapf(err,
"failed to send status code")
return
}
return
}

Builds at commandline but fails to build as gae app

No issues building at commandline:
Darians-MacBook-Pro:gdriveweb darianhickman$ go build helloworld/hello.go
Darians-MacBook-Pro:gdriveweb darianhickman$
Error at locahost:8080/
The Go application could not be built.
(Executed command: /Users/darianhickman/go_appengine/goroot/bin/go-app-builder -app_base /Users/darianhickman/gowork/src/bitbucket.org/darian_hickman/gdriveweb/helloworld -arch 6 -dynamic -goroot /Users/darianhickman/go_appengine/goroot -nobuild_files ^^$ -unsafe -gopath /Users/darianhickman/gowork -binary_name _go_app -extra_imports appengine_internal/init -work_dir /var/folders/fk/wknp5jzn53gbgbml0yn695_m0000gn/T/tmpsHFP6tappengine-go-bin -gcflags -I,/Users/darianhickman/go_appengine/goroot/pkg/darwin_amd64_appengine -ldflags -L,/Users/darianhickman/go_appengine/goroot/pkg/darwin_amd64_appengine hello.go)
/Users/darianhickman/gowork/src/golang.org/x/net/context/ctxhttp/ctxhttp.go:35: req.Cancel undefined (type *http.Request has no field or method Cancel)
2016/05/24 19:39:17 go-app-builder: build timing: 6×6g (469ms total), 0×6l (0 total)
2016/05/24 19:39:17 go-app-builder: failed running 6g: exit status 1
When I research the error
*http.Request has no field or method Cancel
it leads to a bunch of nonapplicable posts about updating to >Go1.5.
Source:
package hello
import (
"encoding/json"
"fmt"
"golang.org/x/net/context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/drive/v3"
_ "google.golang.org/appengine/urlfetch"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"
"os/user"
"path/filepath"
)
const (
assetfolder = "0B-zdryEj60U_MXVkajFweXBQWHM"
)
var (
dir *drive.FileList
)
func init() {
http.HandleFunc("/", handler)
ctx := context.Background()
b, err := ioutil.ReadFile("client_secret.json")
if err != nil {
log.Fatalf("Unable to read client secret file: %v", err)
}
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/drive-go-quickstart.json
config, err := google.ConfigFromJSON(b, drive.DriveMetadataReadonlyScope)
if err != nil {
log.Fatalf("Unable to parse client secret file to config: %v", err)
}
client := getClient(ctx, config)
srv, err := drive.New(client)
if err != nil {
log.Fatalf("Unable to retrieve drive Client %v", err)
}
dir, err = srv.Files.List().PageSize(10).
Fields("nextPageToken, files(id, name)").Do()
if err != nil {
log.Fatalf("Unable to retrieve files.", err)
}
}
func handler(w http.ResponseWriter, r *http.Request) {
//fmt.Fprint(w, r.RequestURI)
fmt.Fprint(w, "Files:")
if len(dir.Files) > 0 {
for _, i := range dir.Files {
fmt.Fprint(w, "%s (%s)\n", i.Name, i.Id)
}
} else {
fmt.Fprint(w, "No files found.")
}
}
// getClient uses a Context and Config to retrieve a Token
// then generate a Client. It returns the generated Client.
func getClient(ctx context.Context, config *oauth2.Config) *http.Client {
cacheFile, err := tokenCacheFile()
if err != nil {
log.Fatalf("Unable to get path to cached credential file. %v", err)
}
tok, err := tokenFromFile(cacheFile)
if err != nil {
tok = getTokenFromWeb(config)
saveToken(cacheFile, tok)
}
return config.Client(ctx, tok)
}
// getTokenFromWeb uses Config to request a Token.
// It returns the retrieved Token.
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
fmt.Printf("Go to the following link in your browser then type the "+
"authorization code: \n%v\n", authURL)
var code string
if _, err := fmt.Scan(&code); err != nil {
log.Fatalf("Unable to read authorization code %v", err)
}
tok, err := config.Exchange(oauth2.NoContext, code)
if err != nil {
log.Fatalf("Unable to retrieve token from web %v", err)
}
return tok
}
// tokenCacheFile generates credential file path/filename.
// It returns the generated credential path/filename.
func tokenCacheFile() (string, error) {
usr, err := user.Current()
if err != nil {
return "", err
}
tokenCacheDir := filepath.Join(usr.HomeDir, ".credentials")
os.MkdirAll(tokenCacheDir, 0700)
return filepath.Join(tokenCacheDir,
url.QueryEscape("drive-go-quickstart.json")), err
}
// tokenFromFile retrieves a Token from a given file path.
// It returns the retrieved Token and any read error encountered.
func tokenFromFile(file string) (*oauth2.Token, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
t := &oauth2.Token{}
err = json.NewDecoder(f).Decode(t)
defer f.Close()
return t, err
}
// saveToken uses a file path to create a file and store the
// token in it.
func saveToken(file string, token *oauth2.Token) {
fmt.Printf("Saving credential file to: %s\n", file)
f, err := os.Create(file)
if err != nil {
log.Fatalf("Unable to cache oauth token: %v", err)
}
defer f.Close()
json.NewEncoder(f).Encode(token)
}
func main() {
ctx := context.Background()
b, err := ioutil.ReadFile("client_secret.json")
if err != nil {
log.Fatalf("Unable to read client secret file: %v", err)
}
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/drive-go-quickstart.json
config, err := google.ConfigFromJSON(b, drive.DriveMetadataReadonlyScope)
if err != nil {
log.Fatalf("Unable to parse client secret file to config: %v", err)
}
client := getClient(ctx, config)
srv, err := drive.New(client)
if err != nil {
log.Fatalf("Unable to retrieve drive Client %v", err)
}
r, err := srv.Files.List().PageSize(10).
Fields("nextPageToken, files(id, name)").Do()
if err != nil {
log.Fatalf("Unable to retrieve files.", err)
}
fmt.Println("Files:")
if len(r.Files) > 0 {
for _, i := range r.Files {
fmt.Printf("%s (%s)\n", i.Name, i.Id)
}
} else {
fmt.Print("No files found.")
}
}
I got past this issue by redownloading and reinstalling Go App Engine SDK . My best guess why that worked is that an old version of go was somehow getting included.

blobstore.ParseUpload acts differently in dev server and deployment

I'm trying to send a multipart/form with both a file and an access token,
it works fine with the dev server, but the exact same post to AppEngine deployment result in a different received token string (I can see that its length is a longer. 938 chars when its supposed to be 902).
I'm actually executing the exact same POST request:
curl -X POST --form "token=<ACCESS_TOKEN>" --form "file=#myfile.jpg" http://upload_url
the upload response handler:
c := appengine.NewContext(r)
blobs, values, err := blobstore.ParseUpload(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
files := blobs["file"]
if len(files) == 0 {
fmt.Fprintln(w, "No file uploaded")
return
}
token := values.Get("token")
EDIT: I tried to simply create an endpoint for posting the token and printing its length, which returns the correct length.. what am I doing wrong ?
func t(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "%d", len(r.FormValue("token")))
}
EDIT2: when I print the received token from the AppEngine deployment I get something like:
eyJhbGciOiJSUzI1NiIsImtpZCI6ImZjZmQ4NGYxZGZhN2NiODUyMTg4MDFkNDRjNzYwNDFmMzB=
lMzg2OGIifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXVkIjoiMjEwMTAyMTk5NDI=
4LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwidG9rZW5faGFzaCI6IklQMmduQjFsZGMwTE=
VEdVg5LWlZa2ciLCJhdF9oYXNoIjoiSVAyZ25CMWxkYzBMRUR1WDktaVlrZyIsImlkIjoiMTA5O=
.
.
it has line breaks... for some reason the dev server doesn't behave like that and doesn't split the lines.
how can I get the original string or stop this behavior ?
How about using multiplart.Reader?
c := appengine.NewContext(r)
if r.Method != "POST" {
http.Error(w, "invalid request", 400)
return
}
ct := r.Header.Get("Content-Type")
if strings.SplitN(ct, ";", 2)[0] != "multipart/form-data" {
http.Error(w, "invalid request", 40400)
return
}
_, params, err := mime.ParseMediaType(ct)
if err != nil {
http.Error(w, "invalid request", 400)
return
}
boundary, ok := params["boundary"]
if !ok {
http.Error(w, "invalid request", 400)
return
}
reader := multipart.NewReader(r.Body, boundary)
var data []byte
for {
part, err := reader.NextPart()
if part == nil || err != nil {
break
}
if part.FormName() != "file" {
continue
}
v := part.Header.Get("Content-Disposition")
if v == "" {
continue
}
d, _, err := mime.ParseMediaType(v)
if err != nil {
continue
}
if d != "form-data" {
continue
}
data, _ = ioutil.ReadAll(part)
// do something using data
}

Resources